LCOV - code coverage report
Current view: top level - vm - exceptions.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 236 414 57.0 %
Date: 2017-07-14 10:03:36 Functions: 38 59 64.4 %

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

Generated by: LCOV version 1.11