LCOV - code coverage report
Current view: top level - vm - exceptions.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 242 420 57.6 %
Date: 2015-06-10 18:10:59 Functions: 39 60 65.0 %

          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     3195331 : java_handle_t *exceptions_get_exception(void)
      77             : {
      78     3195331 :         threadobject *t = THREADOBJECT;
      79             : 
      80             :         /* Get the exception. */
      81             : 
      82             :         LLNI_CRITICAL_START;
      83             : 
      84     3195331 :         java_object_t *o = t->_exceptionptr;
      85     3195331 :         java_handle_t *e = LLNI_WRAP(o);
      86             : 
      87             :         LLNI_CRITICAL_END;
      88             : 
      89             :         /* Return the exception. */
      90             : 
      91     3195331 :         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       33827 : void exceptions_clear_exception(void)
     128             : {
     129       33827 :         threadobject *t = THREADOBJECT;
     130             : 
     131             :         /* Set the exception. */
     132             : 
     133             :         LOG("[exceptions_clear_exception: t=" << (void *) t << cacao::nl);
     134             : 
     135       33827 :         t->_exceptionptr = NULL;
     136       33827 : }
     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     3100849 : java_handle_t *exceptions_get_and_clear_exception(void)
     147             : {
     148             :         java_handle_t *o;
     149             : 
     150             :         /* Get the exception... */
     151             : 
     152     3100849 :         o = exceptions_get_exception();
     153             : 
     154             :         /* ...and clear the exception if it is set. */
     155             : 
     156     3100911 :         if (o != NULL)
     157       20869 :                 exceptions_clear_exception();
     158             : 
     159             :         /* return the exception */
     160             : 
     161     3100911 :         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_asm_new_abstractmethoderror **************************************
     581             : 
     582             :    Generates a java.lang.AbstractMethodError for
     583             :    asm_abstractmethoderror.
     584             : 
     585             : *******************************************************************************/
     586             : 
     587           1 : java_object_t *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
     588             : {
     589             :         stackframeinfo_t  sfi;
     590             :         java_handle_t    *e;
     591             :         java_object_t    *o;
     592             : 
     593             :         /* Fill and add a stackframeinfo (XPC is equal to RA). */
     594             : 
     595           1 :         stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ra);
     596             : 
     597             :         /* create the exception */
     598             : 
     599             : #if defined(ENABLE_JAVASE)
     600           1 :         e = exceptions_new_abstractmethoderror();
     601             : #else
     602             :         e = exceptions_new_error(utf8::java_lang_AbstractMethodError);
     603             : #endif
     604             : 
     605             :         /* Remove the stackframeinfo. */
     606             : 
     607           1 :         stacktrace_stackframeinfo_remove(&sfi);
     608             : 
     609             :         /* unwrap the exception */
     610             :         /* ATTENTION: do the this _after_ the stackframeinfo was removed */
     611             : 
     612           1 :         o = LLNI_UNWRAP(e);
     613             : 
     614           1 :         return o;
     615             : }
     616             : 
     617             : 
     618             : /* exceptions_new_arraystoreexception ******************************************
     619             : 
     620             :    Generates a java.lang.ArrayStoreException for the VM.
     621             : 
     622             : *******************************************************************************/
     623             : 
     624           6 : java_handle_t *exceptions_new_arraystoreexception(void)
     625             : {
     626             :         java_handle_t *o;
     627             : 
     628           6 :         o = exceptions_new_utf(utf8::java_lang_ArrayStoreException);
     629             : 
     630           6 :         return o;
     631             : }
     632             : 
     633             : 
     634             : /* exceptions_throw_abstractmethoderror ****************************************
     635             : 
     636             :    Generates and throws a java.lang.AbstractMethodError for the VM.
     637             : 
     638             : *******************************************************************************/
     639             : 
     640           0 : void exceptions_throw_abstractmethoderror(void)
     641             : {
     642           0 :         exceptions_throw_utf(utf8::java_lang_AbstractMethodError);
     643           0 : }
     644             : 
     645             : 
     646             : /* exceptions_throw_classcircularityerror **************************************
     647             : 
     648             :    Generates and throws a java.lang.ClassCircularityError for the
     649             :    classloader.
     650             : 
     651             :    IN:
     652             :       c....the class in which the error was found
     653             : 
     654             : *******************************************************************************/
     655             : 
     656           0 : void exceptions_throw_classcircularityerror(classinfo *c)
     657             : {
     658           0 :         exceptions_throw_utf_utf(utf8::java_lang_ClassCircularityError, c->name);
     659           0 : }
     660             : 
     661             : 
     662             : /* exceptions_throw_classformaterror *******************************************
     663             : 
     664             :    Generates and throws a java.lang.ClassFormatError for the VM.
     665             : 
     666             :    IN:
     667             :       c............the class in which the error was found
     668             :           message......UTF-8 format string
     669             : 
     670             : *******************************************************************************/
     671             : 
     672           0 : void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
     673             : {
     674             :         va_list  ap;
     675             : 
     676             :         /* allocate a buffer */
     677             : 
     678           0 :         Buffer<> buf;
     679             : 
     680             :         /* print message into allocated buffer */
     681             : 
     682           0 :         if (c != NULL)
     683           0 :                 buf.write_slash_to_dot(c->name).write('(');
     684             : 
     685           0 :         va_start(ap, message);
     686           0 :         buf.writevf(message,ap);
     687           0 :         va_end(ap);
     688             : 
     689           0 :         if (c != NULL)
     690           0 :                 buf.write(')');
     691             : 
     692           0 :         Utf8String u = buf.utf8_str();
     693           0 :         assert(u);
     694             : 
     695             :         /* throw exception */
     696             : 
     697           0 :         exceptions_throw_classformaterror(c, u);
     698           0 : }
     699             : 
     700           0 : void exceptions_throw_classformaterror(classinfo *c, Utf8String message)
     701             : {
     702             :         /* throw exception */
     703             : 
     704           0 :         assert(message);
     705             : 
     706           0 :         exceptions_throw_utf_utf(utf8::java_lang_ClassFormatError, message);
     707           0 : }
     708             : 
     709             : /* exceptions_throw_classnotfoundexception *************************************
     710             : 
     711             :    Generates and throws a java.lang.ClassNotFoundException for the
     712             :    VM.
     713             : 
     714             :    IN:
     715             :       name.........name of the class not found as a Utf8String 
     716             : 
     717             : *******************************************************************************/
     718             : 
     719         769 : void exceptions_throw_classnotfoundexception(Utf8String name)
     720             : {       
     721             :         // We can't use the cached class_java_lang_ClassNotFoundException because
     722             :         // when there are bootstrap classpath problems it has not been set yet,
     723             :         // which leads to confusing error messages.
     724             : 
     725         769 :         exceptions_throw_utf_utf(utf8::java_lang_ClassNotFoundException, name);
     726         769 : }
     727             : 
     728             : 
     729             : /* exceptions_throw_noclassdeffounderror ***************************************
     730             : 
     731             :    Generates and throws a java.lang.NoClassDefFoundError.
     732             : 
     733             :    IN:
     734             :       name.........name of the class not found as a Utf8String 
     735             : 
     736             : *******************************************************************************/
     737             : 
     738           0 : void exceptions_throw_noclassdeffounderror(Utf8String name)
     739             : {
     740           0 :         exceptions_throw_utf_utf(utf8::java_lang_NoClassDefFoundError, name);
     741           0 : }
     742             : 
     743             : 
     744             : /* exceptions_throw_noclassdeffounderror_cause *********************************
     745             : 
     746             :    Generates and throws a java.lang.NoClassDefFoundError with the
     747             :    given cause.
     748             : 
     749             : *******************************************************************************/
     750             : 
     751           3 : void exceptions_throw_noclassdeffounderror_cause(java_handle_t *cause)
     752             : {
     753           3 :         exceptions_throw_utf_cause(utf8::java_lang_NoClassDefFoundError, cause);
     754           3 : }
     755             : 
     756             : 
     757             : /* exceptions_throw_noclassdeffounderror_wrong_name ****************************
     758             : 
     759             :    Generates and throws a java.lang.NoClassDefFoundError with a
     760             :    specific message:
     761             : 
     762             :    IN:
     763             :       name.........name of the class not found as a Utf8String 
     764             : 
     765             : *******************************************************************************/
     766             : 
     767           0 : void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, Utf8String name)
     768             : {
     769           0 :         Buffer<> buf;
     770             : 
     771             :         buf.write_slash_to_dot(c->name)
     772             :            .write(" (wrong name: ", 14)
     773             :            .write_slash_to_dot(name)
     774           0 :            .write(')');
     775             : 
     776           0 :         exceptions_throw_noclassdeffounderror(buf.utf8_str());
     777           0 : }
     778             : 
     779             : 
     780             : /* exceptions_throw_exceptionininitializererror ********************************
     781             : 
     782             :    Generates and throws a java.lang.ExceptionInInitializerError for
     783             :    the VM.
     784             : 
     785             :    IN:
     786             :       cause......cause exception object
     787             : 
     788             : *******************************************************************************/
     789             : 
     790           3 : void exceptions_throw_exceptionininitializererror(java_handle_t *cause)
     791             : {
     792             :         exceptions_throw_utf_throwable(utf8::java_lang_ExceptionInInitializerError,
     793           3 :                                                                    cause);
     794           3 : }
     795             : 
     796             : 
     797             : /* exceptions_throw_incompatibleclasschangeerror *******************************
     798             : 
     799             :    Generates and throws a java.lang.IncompatibleClassChangeError for
     800             :    the VM.
     801             : 
     802             :    IN:
     803             :       message......UTF-8 message format string
     804             : 
     805             : *******************************************************************************/
     806             : 
     807           0 : void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
     808             : {
     809             :         /* allocate memory */
     810             : 
     811           0 :         Buffer<> buf;
     812             : 
     813             :         buf.write_slash_to_dot(c->name)
     814           0 :            .write(message);
     815             : 
     816             :         /* throw exception */
     817             : 
     818           0 :         exceptions_throw_utf_utf(utf8::java_lang_IncompatibleClassChangeError, buf.utf8_str());
     819           0 : }
     820             : 
     821             : 
     822             : /* exceptions_throw_instantiationerror *****************************************
     823             : 
     824             :    Generates and throws a java.lang.InstantiationError for the VM.
     825             : 
     826             : *******************************************************************************/
     827             : 
     828           0 : void exceptions_throw_instantiationerror(classinfo *c)
     829             : {
     830           0 :         exceptions_throw_utf_utf(utf8::java_lang_InstantiationError, c->name);
     831           0 : }
     832             : 
     833             : 
     834             : /* exceptions_throw_internalerror **********************************************
     835             : 
     836             :    Generates and throws a java.lang.InternalError for the VM.
     837             : 
     838             :    IN:
     839             :       message......UTF-8 message format string
     840             : 
     841             : *******************************************************************************/
     842             : 
     843           0 : void exceptions_throw_internalerror(const char *message, ...)
     844             : {
     845             :         va_list  ap;
     846           0 :         Buffer<> buf;
     847             : 
     848             :         /* generate message */
     849             : 
     850           0 :         va_start(ap, message);
     851           0 :         buf.writevf(message,ap);
     852           0 :         va_end(ap);
     853             : 
     854             :         /* throw exception */
     855             : 
     856           0 :         exceptions_throw_utf_utf(utf8::java_lang_InternalError, buf.utf8_str());
     857           0 : }
     858             : 
     859             : 
     860             : /* exceptions_throw_linkageerror ***********************************************
     861             : 
     862             :    Generates and throws java.lang.LinkageError with an error message.
     863             : 
     864             :    IN:
     865             :       message......UTF-8 message, can be freed after the call
     866             :           c............class related to the error. If this is != NULL
     867             :                        the name of c is appended to the error message.
     868             : 
     869             : *******************************************************************************/
     870             : 
     871           8 : void exceptions_throw_linkageerror(const char *message, classinfo *c)
     872             : {
     873             :         /* generate message */
     874             : 
     875           8 :         Buffer<> buf;
     876             : 
     877           8 :         if (c) {
     878             :                 buf.write_slash_to_dot(c->name)
     879           3 :                    .write(": ");              
     880             :         }
     881             : 
     882           8 :         buf.write(message);
     883             : 
     884           8 :         Utf8String msg = buf.utf8_str();
     885             : 
     886           8 :         exceptions_throw_utf_utf(utf8::java_lang_LinkageError, msg);
     887           8 : }
     888             : 
     889             : 
     890             : /* exceptions_throw_nosuchfielderror *******************************************
     891             : 
     892             :    Generates and throws a java.lang.NoSuchFieldError with an error
     893             :    message.
     894             : 
     895             :    IN:
     896             :       c............class in which the field was not found
     897             :           name.........name of the field
     898             : 
     899             : *******************************************************************************/
     900             : 
     901           4 : void exceptions_throw_nosuchfielderror(classinfo *c, Utf8String name)
     902             : {
     903             :         /* generate message */
     904             : 
     905           4 :         Buffer<> buf;
     906             : 
     907             :         buf.write_slash_to_dot(c->name)
     908             :            .write('.')
     909           4 :            .write(name);
     910             : 
     911           4 :         exceptions_throw_utf_utf(utf8::java_lang_NoSuchFieldError, buf.utf8_str());
     912           4 : }
     913             : 
     914             : 
     915             : /* exceptions_throw_nosuchmethoderror ******************************************
     916             : 
     917             :    Generates and throws a java.lang.NoSuchMethodError with an error
     918             :    message.
     919             : 
     920             :    IN:
     921             :       c............class in which the method was not found
     922             :           name.........name of the method
     923             :           desc.........descriptor of the method
     924             : 
     925             : *******************************************************************************/
     926             : 
     927           0 : void exceptions_throw_nosuchmethoderror(classinfo *c, Utf8String name, Utf8String desc)
     928             : {
     929             :         /* generate message */
     930             : 
     931           0 :         Buffer<> buf;
     932             : 
     933             :         buf.write_slash_to_dot(c->name)
     934             :            .write('.')
     935             :            .write(name)
     936           0 :            .write(desc);
     937             : 
     938             : #if defined(ENABLE_JAVASE)
     939           0 :         exceptions_throw_utf_utf(utf8::java_lang_NoSuchMethodError, buf.utf8_str());
     940             : #else
     941             :         exceptions_throw_utf_utf(utf8::java_lang_Error, buf.utf8_str());
     942             : #endif
     943           0 : }
     944             : 
     945             : 
     946             : /* exceptions_throw_outofmemoryerror *******************************************
     947             : 
     948             :    Generates and throws an java.lang.OutOfMemoryError for the VM.
     949             : 
     950             : *******************************************************************************/
     951             : 
     952           3 : void exceptions_throw_outofmemoryerror(void)
     953             : {
     954             :         exceptions_throw_utf_utf(utf8::java_lang_OutOfMemoryError,
     955           3 :                                  Utf8String::from_utf8("Java heap space"));
     956           3 : }
     957             : 
     958             : 
     959             : /* exceptions_throw_unsatisfiedlinkerror ***************************************
     960             : 
     961             :    Generates and throws a java.lang.UnsatisfiedLinkError for the
     962             :    classloader.
     963             : 
     964             :    IN:
     965             :           name......UTF-8 name string
     966             : 
     967             : *******************************************************************************/
     968             : 
     969           1 : void exceptions_throw_unsatisfiedlinkerror(Utf8String name)
     970             : {
     971             : #if defined(ENABLE_JAVASE)
     972           1 :         exceptions_throw_utf_utf(utf8::java_lang_UnsatisfiedLinkError, name);
     973             : #else
     974             :         exceptions_throw_utf_utf(utf8::java_lang_Error, name);
     975             : #endif
     976           1 : }
     977             : 
     978             : 
     979             : /* exceptions_throw_unsupportedclassversionerror *******************************
     980             : 
     981             :    Generates and throws a java.lang.UnsupportedClassVersionError for
     982             :    the classloader.
     983             : 
     984             : *******************************************************************************/
     985             : 
     986           0 : void exceptions_throw_unsupportedclassversionerror(classinfo *c)
     987             : {
     988             :         /* generate message */
     989             : 
     990           0 :         Buffer<> buf;
     991             : 
     992             :         buf.write_slash_to_dot(c->name)
     993           0 :            .writef(" (Unsupported major.minor version %d.%d)", c->version.majr(), c->version.minr());
     994             : 
     995             :         /* throw exception */
     996             : 
     997           0 :         exceptions_throw_utf_utf(utf8::java_lang_UnsupportedClassVersionError, buf.utf8_str());
     998           0 : }
     999             : 
    1000             : 
    1001             : /* exceptions_throw_verifyerror ************************************************
    1002             : 
    1003             :    Generates and throws a java.lang.VerifyError for the JIT compiler.
    1004             : 
    1005             :    IN:
    1006             :       m............method in which the error was found
    1007             :           message......UTF-8 format string
    1008             : 
    1009             : *******************************************************************************/
    1010             : 
    1011          28 : void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
    1012             : {
    1013             :         va_list  ap;
    1014          28 :         Buffer<> buf;
    1015             : 
    1016             :         /* generate message */
    1017             : 
    1018          28 :         if (m != NULL) {
    1019             :                 buf.write("(class: ")
    1020             :                    .write_slash_to_dot(m->clazz->name)
    1021             :                    .write(", method: ")
    1022             :                    .write(m->name)
    1023             :                    .write(" signature: ")
    1024             :                    .write(m->descriptor)
    1025          28 :                    .write(") ");
    1026             :         }
    1027             : 
    1028          28 :         va_start(ap, message);
    1029          28 :         buf.writevf(message, ap);
    1030          28 :         va_end(ap);
    1031             : 
    1032             :         /* throw exception */
    1033             : 
    1034          28 :         exceptions_throw_utf_utf(utf8::java_lang_VerifyError, buf.utf8_str());
    1035          28 : }
    1036             : 
    1037             : 
    1038             : /* exceptions_throw_verifyerror_for_stack **************************************
    1039             : 
    1040             :    throws a java.lang.VerifyError for an invalid stack slot type
    1041             : 
    1042             :    IN:
    1043             :       m............method in which the error was found
    1044             :           type.........the expected type
    1045             : 
    1046             :    RETURN VALUE:
    1047             :       an exception pointer (in any case -- either it is the newly created
    1048             :           exception, or an exception thrown while trying to create it).
    1049             : 
    1050             : *******************************************************************************/
    1051             : 
    1052           8 : void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
    1053             : {
    1054             :         /* generate message */
    1055             : 
    1056           8 :         Buffer<> buf;
    1057             : 
    1058           8 :         if (m != NULL) {
    1059             :                 buf.write("(class: ")
    1060             :                    .write_slash_to_dot(m->clazz->name)
    1061             :                    .write(", method: ")
    1062             :                    .write(m->name)
    1063             :                    .write(" signature: ")
    1064             :                    .write(m->descriptor)
    1065           8 :                    .write(") ");
    1066             :         }
    1067             : 
    1068           8 :         buf.write("Expecting to find ");
    1069             : 
    1070           8 :         switch (type) {
    1071           1 :         case TYPE_INT: buf.write("integer");              break;
    1072           0 :         case TYPE_LNG: buf.write("long");                 break;
    1073           0 :         case TYPE_FLT: buf.write("float");                break;
    1074           0 :         case TYPE_DBL: buf.write("double");               break;
    1075           7 :         case TYPE_ADR: buf.write("object/array");         break;
    1076           0 :         case TYPE_RET: buf.write("returnAddress");        break;
    1077           0 :         default:       buf.write("<INVALID>"); assert(0); break;
    1078             :         }
    1079             : 
    1080           8 :         buf.write(" on stack");
    1081             : 
    1082             :         /* throw exception */
    1083             : 
    1084           8 :         exceptions_throw_utf_utf(utf8::java_lang_VerifyError, buf.utf8_str());
    1085           8 : }
    1086             : 
    1087             : 
    1088             : /* exceptions_new_arithmeticexception ******************************************
    1089             : 
    1090             :    Generates a java.lang.ArithmeticException for the JIT compiler.
    1091             : 
    1092             : *******************************************************************************/
    1093             : 
    1094           8 : java_handle_t *exceptions_new_arithmeticexception(void)
    1095             : {
    1096             :         java_handle_t *o;
    1097             : 
    1098             :         o = exceptions_new_utf_utf(utf8::java_lang_ArithmeticException,
    1099           8 :                                                            utf8::division_by_zero);
    1100             : 
    1101           8 :         return o;
    1102             : }
    1103             : 
    1104             : 
    1105             : /* exceptions_new_arrayindexoutofboundsexception *******************************
    1106             : 
    1107             :    Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
    1108             :    system.
    1109             : 
    1110             : *******************************************************************************/
    1111             : 
    1112          25 : java_handle_t *exceptions_new_arrayindexoutofboundsexception(s4 index)
    1113             : {
    1114             :         java_handle_t *o;
    1115             :         methodinfo    *m;
    1116             :         java_handle_t *s;
    1117             : 
    1118             :         /* convert the index into a String, like Sun does */
    1119             : 
    1120             :         m = class_resolveclassmethod(class_java_lang_String,
    1121             :                                                                  Utf8String::from_utf8("valueOf"),
    1122             :                                                                  Utf8String::from_utf8("(I)Ljava/lang/String;"),
    1123             :                                                                  class_java_lang_Object,
    1124          25 :                                                                  true);
    1125             : 
    1126          25 :         if (m == NULL)
    1127           0 :                 return exceptions_get_exception();
    1128             : 
    1129          25 :         s = vm_call_method(m, NULL, index);
    1130             : 
    1131          25 :         if (s == NULL)
    1132           0 :                 return exceptions_get_exception();
    1133             : 
    1134             :         o = exceptions_new_utf_javastring(utf8::java_lang_ArrayIndexOutOfBoundsException,
    1135          25 :                                                                           s);
    1136             : 
    1137          25 :         if (o == NULL)
    1138           0 :                 return exceptions_get_exception();
    1139             : 
    1140          25 :         return o;
    1141             : }
    1142             : 
    1143             : 
    1144             : /* exceptions_throw_arrayindexoutofboundsexception *****************************
    1145             : 
    1146             :    Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
    1147             :    the VM.
    1148             : 
    1149             : *******************************************************************************/
    1150             : 
    1151           1 : void exceptions_throw_arrayindexoutofboundsexception(void)
    1152             : {
    1153           1 :         exceptions_throw_utf(utf8::java_lang_ArrayIndexOutOfBoundsException);
    1154           1 : }
    1155             : 
    1156             : 
    1157             : /* exceptions_throw_arraystoreexception ****************************************
    1158             : 
    1159             :    Generates and throws a java.lang.ArrayStoreException for the VM.
    1160             : 
    1161             : *******************************************************************************/
    1162             : 
    1163           1 : void exceptions_throw_arraystoreexception(void)
    1164             : {
    1165           1 :         exceptions_throw_utf(utf8::java_lang_ArrayStoreException);
    1166           1 : }
    1167             : 
    1168             : 
    1169             : /* exceptions_new_classcastexception *******************************************
    1170             : 
    1171             :    Generates a java.lang.ClassCastException for the JIT compiler.
    1172             : 
    1173             : *******************************************************************************/
    1174             : 
    1175          10 : java_handle_t *exceptions_new_classcastexception(java_handle_t *o)
    1176             : {
    1177             :         classinfo *c;
    1178             : 
    1179          10 :         LLNI_class_get(o, c);
    1180             : 
    1181          10 :         Utf8String classname = get_classname_for_exception(c);
    1182             : 
    1183          10 :         return exceptions_new_utf_utf(utf8::java_lang_ClassCastException, classname);
    1184             : }
    1185             : 
    1186             : 
    1187             : /* exceptions_throw_clonenotsupportedexception *********************************
    1188             : 
    1189             :    Generates and throws a java.lang.CloneNotSupportedException for the
    1190             :    VM.
    1191             : 
    1192             : *******************************************************************************/
    1193             : 
    1194           0 : void exceptions_throw_clonenotsupportedexception(void)
    1195             : {
    1196           0 :         exceptions_throw_utf(utf8::java_lang_CloneNotSupportedException);
    1197           0 : }
    1198             : 
    1199             : 
    1200             : /* exceptions_throw_illegalaccessexception *************************************
    1201             : 
    1202             :    Generates and throws a java.lang.IllegalAccessException for the VM.
    1203             : 
    1204             : *******************************************************************************/
    1205             : 
    1206           0 : void exceptions_throw_illegalaccessexception(Utf8String message)
    1207             : {
    1208           0 :         exceptions_throw_utf_utf(utf8::java_lang_IllegalAccessException, message);
    1209           0 : }
    1210             : 
    1211             : 
    1212             : /* exceptions_throw_illegalargumentexception ***********************************
    1213             : 
    1214             :    Generates and throws a java.lang.IllegalArgumentException for the
    1215             :    VM.
    1216             : 
    1217             : *******************************************************************************/
    1218             : 
    1219           1 : void exceptions_throw_illegalargumentexception(void)
    1220             : {
    1221           1 :         exceptions_throw_utf(utf8::java_lang_IllegalArgumentException);
    1222           1 : }
    1223             : 
    1224             : 
    1225             : /* exceptions_throw_illegalmonitorstateexception *******************************
    1226             : 
    1227             :    Generates and throws a java.lang.IllegalMonitorStateException for
    1228             :    the VM.
    1229             : 
    1230             : *******************************************************************************/
    1231             : 
    1232           0 : void exceptions_throw_illegalmonitorstateexception(void)
    1233             : {
    1234           0 :         exceptions_throw_utf(utf8::java_lang_IllegalMonitorStateException);
    1235           0 : }
    1236             : 
    1237             : 
    1238             : /* exceptions_throw_instantiationexception *************************************
    1239             : 
    1240             :    Generates and throws a java.lang.InstantiationException for the VM.
    1241             : 
    1242             : *******************************************************************************/
    1243             : 
    1244           0 : void exceptions_throw_instantiationexception(classinfo *c)
    1245             : {
    1246           0 :         exceptions_throw_utf_utf(utf8::java_lang_InstantiationException, c->name);
    1247           0 : }
    1248             : 
    1249             : 
    1250             : /* exceptions_throw_interruptedexception ***************************************
    1251             : 
    1252             :    Generates and throws a java.lang.InterruptedException for the VM.
    1253             : 
    1254             : *******************************************************************************/
    1255             : 
    1256       20000 : void exceptions_throw_interruptedexception(void)
    1257             : {
    1258       20000 :         exceptions_throw_utf(utf8::java_lang_InterruptedException);
    1259       20000 : }
    1260             : 
    1261             : 
    1262             : /* exceptions_throw_invocationtargetexception **********************************
    1263             : 
    1264             :    Generates and throws a java.lang.reflect.InvocationTargetException
    1265             :    for the VM.
    1266             : 
    1267             :    IN:
    1268             :       cause......cause exception object
    1269             : 
    1270             : *******************************************************************************/
    1271             : 
    1272          11 : void exceptions_throw_invocationtargetexception(java_handle_t *cause)
    1273             : {
    1274             :         exceptions_throw_utf_throwable(utf8::java_lang_reflect_InvocationTargetException,
    1275          11 :                                                                    cause);
    1276          11 : }
    1277             : 
    1278             : 
    1279             : /* exceptions_throw_negativearraysizeexception *********************************
    1280             : 
    1281             :    Generates and throws a java.lang.NegativeArraySizeException for the
    1282             :    VM.
    1283             : 
    1284             : *******************************************************************************/
    1285             : 
    1286           5 : void exceptions_throw_negativearraysizeexception(void)
    1287             : {
    1288           5 :         exceptions_throw_utf(utf8::java_lang_NegativeArraySizeException);
    1289           5 : }
    1290             : 
    1291             : 
    1292             : /* exceptions_new_nullpointerexception *****************************************
    1293             : 
    1294             :    Generates a java.lang.NullPointerException for the VM system.
    1295             : 
    1296             : *******************************************************************************/
    1297             : 
    1298          22 : java_handle_t *exceptions_new_nullpointerexception(void)
    1299             : {
    1300             :         java_handle_t *o;
    1301             : 
    1302          22 :         o = exceptions_new_utf(utf8::java_lang_NullPointerException);
    1303             : 
    1304          22 :         return o;
    1305             : }
    1306             : 
    1307             : 
    1308             : /* exceptions_throw_nullpointerexception ***************************************
    1309             : 
    1310             :    Generates a java.lang.NullPointerException for the VM system and
    1311             :    throw it in the VM system.
    1312             : 
    1313             : *******************************************************************************/
    1314             : 
    1315           3 : void exceptions_throw_nullpointerexception(void)
    1316             : {
    1317           3 :         exceptions_throw_utf(utf8::java_lang_NullPointerException);
    1318           3 : }
    1319             : 
    1320             : 
    1321             : /* exceptions_throw_privilegedactionexception **********************************
    1322             : 
    1323             :    Generates and throws a java.security.PrivilegedActionException.
    1324             : 
    1325             : *******************************************************************************/
    1326             : 
    1327           0 : void exceptions_throw_privilegedactionexception(java_handle_t *exception)
    1328             : {
    1329             :         exceptions_throw_utf_exception(utf8::java_security_PrivilegedActionException,
    1330           0 :                                                                    exception);
    1331           0 : }
    1332             : 
    1333             : 
    1334             : /* exceptions_throw_stringindexoutofboundsexception ****************************
    1335             : 
    1336             :    Generates and throws a java.lang.StringIndexOutOfBoundsException
    1337             :    for the VM.
    1338             : 
    1339             : *******************************************************************************/
    1340             : 
    1341           0 : void exceptions_throw_stringindexoutofboundsexception(void)
    1342             : {
    1343           0 :         exceptions_throw_utf(utf8::java_lang_StringIndexOutOfBoundsException);
    1344           0 : }
    1345             : 
    1346             : 
    1347             : /* exceptions_fillinstacktrace *************************************************
    1348             : 
    1349             :    Calls the fillInStackTrace-method of the currently thrown
    1350             :    exception.
    1351             : 
    1352             : *******************************************************************************/
    1353             : 
    1354           3 : java_handle_t *exceptions_fillinstacktrace(void)
    1355             : {
    1356             :         java_handle_t *o;
    1357             :         classinfo     *c;
    1358             :         methodinfo    *m;
    1359             : 
    1360             :         /* get exception */
    1361             : 
    1362           3 :         o = exceptions_get_and_clear_exception();
    1363             : 
    1364           3 :         assert(o);
    1365             : 
    1366             :         /* resolve methodinfo pointer from exception object */
    1367             : 
    1368           3 :         LLNI_class_get(o, c);
    1369             : 
    1370             : #if defined(ENABLE_JAVASE)
    1371             :         m = class_resolvemethod(c,
    1372             :                                                         utf8::fillInStackTrace,
    1373           3 :                                                         utf8::void__java_lang_Throwable);
    1374             : #elif defined(ENABLE_JAVAME_CLDC1_1)
    1375             :         m = class_resolvemethod(c,
    1376             :                                                         utf8::fillInStackTrace,
    1377             :                                                         utf8::void__void);
    1378             : #else
    1379             : #error IMPLEMENT ME!
    1380             : #endif
    1381             : 
    1382             :         /* call function */
    1383             : 
    1384           3 :         (void) vm_call_method(m, o);
    1385             : 
    1386             :         /* return exception object */
    1387             : 
    1388           3 :         return o;
    1389             : }
    1390             : 
    1391             : 
    1392             : /* exceptions_handle_exception *************************************************
    1393             : 
    1394             :    Try to find an exception handler for the given exception and return it.
    1395             :    If no handler is found, exit the monitor of the method (if any)
    1396             :    and return NULL.
    1397             : 
    1398             :    IN:
    1399             :       xptr.........the exception object
    1400             :           xpc..........PC of where the exception was thrown
    1401             :           pv...........Procedure Value of the current method
    1402             :           sp...........current stack pointer
    1403             : 
    1404             :    RETURN VALUE:
    1405             :       the address of the first matching exception handler, or
    1406             :           NULL if no handler was found
    1407             : 
    1408             : *******************************************************************************/
    1409             : 
    1410             : #if defined(ENABLE_JIT)
    1411       41546 : extern "C" void *exceptions_handle_exception(java_object_t *xptro, void *xpc, void *pv, void *sp)
    1412             : {
    1413             :         stackframeinfo_t        sfi;
    1414             :         java_handle_t          *xptr;
    1415             :         methodinfo             *m;
    1416             :         codeinfo               *code;
    1417             :         exceptiontable_t       *et;
    1418             :         exceptiontable_entry_t *ete;
    1419             :         s4                      i;
    1420             :         classref_or_classinfo   cr;
    1421             :         classinfo              *c;
    1422             :         void                   *result;
    1423             : 
    1424             : #ifdef __S390__
    1425             :         /* Addresses are 31 bit integers */
    1426             : #       define ADDR_MASK(x) (void *) ((uintptr_t) (x) & 0x7FFFFFFF)
    1427             : #else
    1428             : #       define ADDR_MASK(x) (x)
    1429             : #endif
    1430             : 
    1431       41546 :         xptr = LLNI_WRAP(xptro);
    1432       41546 :         xpc  = ADDR_MASK(xpc);
    1433             : 
    1434             :         /* Fill and add a stackframeinfo (XPC is equal to RA). */
    1435             : 
    1436       41546 :         stacktrace_stackframeinfo_add(&sfi, pv, sp, xpc, xpc);
    1437             : 
    1438       41546 :         result = NULL;
    1439             : 
    1440             :         /* Get the codeinfo for the current method. */
    1441             : 
    1442       41546 :         code = code_get_codeinfo_for_pv(pv);
    1443             : 
    1444             :         /* Get the methodinfo pointer from the codeinfo pointer. For
    1445             :            asm_vm_call_method the codeinfo pointer is NULL and we simply
    1446             :            can return the proper exception handler. */
    1447             : 
    1448       41546 :         if (code == NULL) {
    1449          60 :                 result = (void *) (uintptr_t) &asm_vm_call_method_exception_handler;
    1450          60 :                 goto exceptions_handle_exception_return;
    1451             :         }
    1452             : 
    1453       41486 :         m = code->m;
    1454             : 
    1455             : #if !defined(NDEBUG)
    1456             :         /* print exception trace */
    1457             : 
    1458       41486 :         if (opt_TraceExceptions)
    1459           0 :                 trace_exception(LLNI_DIRECT(xptr), m, xpc);
    1460             : #endif
    1461             : 
    1462             :         /* Get the exception table. */
    1463             : 
    1464       41486 :         et = code->exceptiontable;
    1465             : 
    1466       41486 :         if (et != NULL) {
    1467             :         /* Iterate over all exception table entries. */
    1468             : 
    1469       21074 :         ete = et->entries;
    1470             : 
    1471       22501 :         for (i = 0; i < et->length; i++, ete++) {
    1472             :                 /* is the xpc is the current catch range */
    1473             : 
    1474       22392 :                 if ((ADDR_MASK(ete->startpc) <= xpc) && (xpc < ADDR_MASK(ete->endpc))) {
    1475       20987 :                         cr = ete->catchtype;
    1476             : 
    1477             :                         /* NULL catches everything */
    1478             : 
    1479       20987 :                         if (cr.any == NULL) {
    1480             : #if !defined(NDEBUG)
    1481             :                                 /* Print stacktrace of exception when caught. */
    1482             : 
    1483           0 :                                 if (opt_TraceExceptions) {
    1484           0 :                                         exceptions_print_exception(xptr);
    1485           0 :                                         stacktrace_print_exception(xptr);
    1486             :                                 }
    1487             : #endif
    1488             : 
    1489           0 :                                 result = ete->handlerpc;
    1490           0 :                                 goto exceptions_handle_exception_return;
    1491             :                         }
    1492             : 
    1493             :                         /* resolve or load/link the exception class */
    1494             : 
    1495       20987 :                         if (cr.is_classref()) {
    1496             :                                 /* The exception class reference is unresolved. */
    1497             :                                 /* We have to do _eager_ resolving here. While the
    1498             :                                    class of the exception object is guaranteed to be
    1499             :                                    loaded, it may well have been loaded by a different
    1500             :                                    loader than the defining loader of m's class, which
    1501             :                                    is the one we must use to resolve the catch
    1502             :                                    class. Thus lazy resolving might fail, even if the
    1503             :                                    result of the resolution would be an already loaded
    1504             :                                    class. */
    1505             : 
    1506         121 :                                 c = resolve_classref_eager(cr.ref);
    1507             : 
    1508         121 :                                 if (c == NULL) {
    1509             :                                         /* Exception resolving the exception class, argh! */
    1510           0 :                                         goto exceptions_handle_exception_return;
    1511             :                                 }
    1512             : 
    1513             :                                 /* Ok, we resolved it. Enter it in the table, so we
    1514             :                                    don't have to do this again. */
    1515             :                                 /* XXX this write should be atomic. Is it? */
    1516             : 
    1517         121 :                                 ete->catchtype.cls = c;
    1518             :                         }
    1519             :                         else {
    1520       20866 :                                 c = cr.cls;
    1521             : 
    1522             :                                 /* XXX I don't think this case can ever happen. -Edwin */
    1523       20866 :                                 if (!(c->state & CLASS_LOADED))
    1524             :                                         /* use the methods' classloader */
    1525           0 :                                         if (!load_class_from_classloader(c->name,
    1526             :                                                                                                          m->clazz->classloader))
    1527           0 :                                                 goto exceptions_handle_exception_return;
    1528             : 
    1529             :                                 /* XXX I think, if it is not linked, we can be sure
    1530             :                                    that the exception object is no (indirect) instance
    1531             :                                    of it, no?  -Edwin  */
    1532       20866 :                                 if (!(c->state & CLASS_LINKED))
    1533           0 :                                         if (!link_class(c))
    1534           0 :                                                 goto exceptions_handle_exception_return;
    1535             :                         }
    1536             : 
    1537             :                         /* is the thrown exception an instance of the catch class? */
    1538             : 
    1539       20987 :                         if (builtin_instanceof(xptr, c)) {
    1540             : #if !defined(NDEBUG)
    1541             :                                 /* Print stacktrace of exception when caught. */
    1542             : 
    1543       20965 :                                 if (opt_TraceExceptions) {
    1544           0 :                                         exceptions_print_exception(xptr);
    1545           0 :                                         stacktrace_print_exception(xptr);
    1546             :                                 }
    1547             : #endif
    1548             : 
    1549       20965 :                                 result = ete->handlerpc;
    1550       20965 :                                 goto exceptions_handle_exception_return;
    1551             :                         }
    1552             :                 }
    1553             :         }
    1554             :         }
    1555             : 
    1556             :         /* Is this method realization synchronized? */
    1557             : 
    1558       20521 :         if (code_is_synchronized(code)) {
    1559             :                 /* Get synchronization object. */
    1560             : 
    1561          87 :                 java_object_t *o = *((java_object_t **) (((uintptr_t) sp) + code->synchronizedoffset));
    1562             : 
    1563          87 :                 assert(o != NULL);
    1564             : 
    1565          87 :                 lock_monitor_exit(LLNI_QUICKWRAP(o));
    1566             :         }
    1567             : 
    1568             :         /* none of the exceptions catch this one */
    1569             : 
    1570             : #if !defined(NDEBUG)
    1571             : 
    1572             : # if defined(ENABLE_DEBUG_FILTER)
    1573       20521 :         if (show_filters_test_verbosecall_exit(m)) {
    1574             : # endif
    1575             : 
    1576             :         /* outdent the log message */
    1577             : 
    1578           0 :         if (opt_verbosecall) {
    1579           0 :                 if (TRACEJAVACALLINDENT)
    1580           0 :                         TRACEJAVACALLINDENT--;
    1581             :                 else
    1582           0 :                         log_text("exceptions_handle_exception: WARNING: unmatched unindent");
    1583             :         }
    1584             : 
    1585             : # if defined(ENABLE_DEBUG_FILTER)
    1586             :         }
    1587             : # endif
    1588             : #endif /* !defined(NDEBUG) */
    1589             : 
    1590       20521 :         result = NULL;
    1591             : 
    1592             : exceptions_handle_exception_return:
    1593             : 
    1594             :         /* Remove the stackframeinfo. */
    1595             : 
    1596       41546 :         stacktrace_stackframeinfo_remove(&sfi);
    1597             : 
    1598       41546 :         return result;
    1599             : }
    1600             : #endif /* defined(ENABLE_JIT) */
    1601             : 
    1602             : 
    1603             : /* exceptions_print_exception **************************************************
    1604             : 
    1605             :    Prints an exception, the detail message and the cause, if
    1606             :    available, with CACAO internal functions to stdout.
    1607             : 
    1608             : *******************************************************************************/
    1609             : 
    1610           0 : void exceptions_print_exception(java_handle_t *xptr)
    1611             : {
    1612           0 :         java_lang_Throwable jlt(xptr);
    1613             : 
    1614           0 :         if (jlt.is_null()) {
    1615           0 :                 puts("NULL\n");
    1616             :                 return;
    1617             :         }
    1618             : 
    1619             : #if defined(ENABLE_JAVASE)
    1620           0 :         java_lang_Throwable jltcause(jlt.get_cause());
    1621             : #endif
    1622             : 
    1623             :         /* print the root exception */
    1624             : 
    1625           0 :         classinfo* c = jlt.get_Class();
    1626           0 :         utf_display_printable_ascii_classname(c->name);
    1627             : 
    1628           0 :         java_lang_String jls(jlt.get_detailMessage());
    1629             : 
    1630           0 :         if (!jls.is_null()) {
    1631           0 :                 JavaString str = jls.get_handle();
    1632             : 
    1633           0 :                 printf(": ");
    1634           0 :                 str.fprint_printable_ascii(stdout);
    1635             :         }
    1636             : 
    1637           0 :         putc('\n', stdout);
    1638             : 
    1639             : #if defined(ENABLE_JAVASE)
    1640             :         /* print the cause if available */
    1641             : 
    1642             :         // FIXME cause != t compare with operator override.
    1643           0 :         if ((!jltcause.is_null()) && (jltcause.get_handle() != jlt.get_handle())) {
    1644           0 :                 printf("Caused by: ");
    1645             : 
    1646           0 :                 c = jltcause.get_Class();
    1647           0 :                 utf_display_printable_ascii_classname(c->name);
    1648             : 
    1649           0 :                 java_lang_String jlscause(jlt.get_detailMessage());
    1650             : 
    1651           0 :                 if (jlscause.get_handle() != NULL) {
    1652           0 :                         JavaString str = jls.get_handle();
    1653             : 
    1654           0 :                         printf(": ");
    1655           0 :                         str.fprint_printable_ascii(stdout);
    1656             :                 }
    1657             : 
    1658           0 :                 putc('\n', stdout);
    1659           0 :         }
    1660             : #endif
    1661             : }
    1662             : 
    1663             : 
    1664             : /* exceptions_print_current_exception ******************************************
    1665             : 
    1666             :    Prints the current pending exception, the detail message and the
    1667             :    cause, if available, with CACAO internal functions to stdout.
    1668             : 
    1669             : *******************************************************************************/
    1670             : 
    1671           0 : void exceptions_print_current_exception(void)
    1672             : {
    1673             :         java_handle_t *o;
    1674             : 
    1675           0 :         o = exceptions_get_exception();
    1676             : 
    1677           0 :         exceptions_print_exception(o);
    1678           0 : }
    1679             : 
    1680             : 
    1681             : /* exceptions_print_stacktrace *************************************************
    1682             : 
    1683             :    Prints a pending exception with Throwable.printStackTrace().  If
    1684             :    there happens an exception during printStackTrace(), we print the
    1685             :    thrown exception and the original one.
    1686             : 
    1687             :    NOTE: This function calls Java code.
    1688             : 
    1689             : *******************************************************************************/
    1690             : 
    1691          41 : void exceptions_print_stacktrace(void)
    1692             : {
    1693             :         java_handle_t    *e;
    1694             :         java_handle_t    *ne;
    1695             :         classinfo        *c;
    1696             :         methodinfo       *m;
    1697             : 
    1698             :         /* Get and clear exception because we are calling Java code
    1699             :            again. */
    1700             : 
    1701          41 :         e = exceptions_get_and_clear_exception();
    1702             : 
    1703          41 :         if (e == NULL)
    1704           0 :                 return;
    1705             : 
    1706             : #if 0
    1707             :         /* FIXME Enable me. */
    1708             :         if (builtin_instanceof(e, class_java_lang_ThreadDeath)) {
    1709             :                 /* Don't print anything if we are being killed. */
    1710             :         }
    1711             :         else
    1712             : #endif
    1713             :         {
    1714             :                 /* Get the exception class. */
    1715             : 
    1716          41 :                 LLNI_class_get(e, c);
    1717             : 
    1718             :                 /* Find the printStackTrace() method. */
    1719             : 
    1720             :                 m = class_resolveclassmethod(c,
    1721             :                                                                          utf8::printStackTrace,
    1722             :                                                                          utf8::void__void,
    1723             :                                                                          class_java_lang_Object,
    1724          41 :                                                                          false);
    1725             : 
    1726          41 :                 if (m == NULL)
    1727           0 :                         os::abort("exceptions_print_stacktrace: printStackTrace()V not found");
    1728             : 
    1729             :                 /* Print message. */
    1730             : 
    1731          41 :                 fprintf(stderr, "Exception ");
    1732             : 
    1733             :                 /* Print thread name.  We get the thread here explicitly as we
    1734             :                    need it afterwards. */
    1735             : 
    1736          41 :                 threadobject     *t  = thread_get_current();
    1737          41 :                 java_lang_Thread *to = (java_lang_Thread *) LLNI_WRAP(t->object);
    1738             : 
    1739          41 :                 if (to != NULL) {
    1740          41 :                         fprintf(stderr, "in thread \"");
    1741          41 :                         thread_fprint_name(t, stderr);
    1742          41 :                         fprintf(stderr, "\" ");
    1743             :                 }
    1744             : 
    1745             :                 /* Print the stacktrace. */
    1746             : 
    1747          41 :                 if (builtin_instanceof(e, class_java_lang_Throwable)) {
    1748          41 :                         (void) vm_call_method(m, e);
    1749             : 
    1750             :                         /* If this happens we are EXTREMLY out of memory or have a
    1751             :                            serious problem while printStackTrace.  But may be
    1752             :                            another exception, so print it. */
    1753             : 
    1754          41 :                         ne = exceptions_get_exception();
    1755             : 
    1756          41 :                         if (ne != NULL) {
    1757           0 :                                 fprintf(stderr, "Exception while printStackTrace(): ");
    1758             : 
    1759             :                                 /* Print the current exception. */
    1760             : 
    1761           0 :                                 exceptions_print_exception(ne);
    1762           0 :                                 stacktrace_print_exception(ne);
    1763             : 
    1764             :                                 /* Now print the original exception. */
    1765             : 
    1766           0 :                                 fprintf(stderr, "Original exception was: ");
    1767           0 :                                 exceptions_print_exception(e);
    1768           0 :                                 stacktrace_print_exception(e);
    1769             :                         }
    1770             :                 }
    1771             :                 else {
    1772           0 :                         fprintf(stderr, ". Uncaught exception of type ");
    1773             : #if !defined(NDEBUG)
    1774             :                         /* FIXME This prints to stdout. */
    1775           0 :                         class_print(c);
    1776             : #else
    1777             :                         fprintf(stderr, "UNKNOWN");
    1778             : #endif
    1779           0 :                         fprintf(stderr, ".");
    1780             :                 }
    1781             : 
    1782          41 :                 fflush(stderr);
    1783             :         }
    1784             : }
    1785             : 
    1786          10 : static inline Utf8String get_classname_for_exception(classinfo *c) {
    1787             : #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
    1788             :         return Utf8String::from_utf8_slash_to_dot(c->name.begin(), c->name.size());
    1789             : #else
    1790          10 :         return c->name;
    1791             : #endif
    1792             : }
    1793             : 
    1794             : /*
    1795             :  * These are local overrides for various environment variables in Emacs.
    1796             :  * Please do not remove this and leave it at the end of the file, where
    1797             :  * Emacs will automagically detect them.
    1798             :  * ---------------------------------------------------------------------
    1799             :  * Local variables:
    1800             :  * mode: c++
    1801             :  * indent-tabs-mode: t
    1802             :  * c-basic-offset: 4
    1803             :  * tab-width: 4
    1804             :  * End:
    1805             :  * vim:noexpandtab:sw=4:ts=4:
    1806             :  */

Generated by: LCOV version 1.11