home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / kaffe-0.5p4-src.tgz / tar.out / contrib / kaffe / kaffevm / jit / exception.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  6KB  |  252 lines

  1. /*
  2.  * exception.c
  3.  * Handle exceptions for the translator.
  4.  *
  5.  * Copyright (c) 1996 Systems Architecture Research Centre,
  6.  *           City University, London, UK.
  7.  *
  8.  * See the file "license.terms" for information on usage and redistribution
  9.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  10.  *
  11.  * Written by Tim Wilkinson <tim@sarc.city.ac.uk>, June 1996.
  12.  */
  13.  
  14. #include "config.h"
  15. #include <stdio.h>
  16. #include <assert.h>
  17. #include <stdlib.h>
  18. #include <signal.h>
  19. #include "gtypes.h"
  20. #include "access.h"
  21. #include "object.h"
  22. #include "constants.h"
  23. #include "classMethod.h"
  24. #include "exception.h"
  25. #include "baseClasses.h"
  26. #include "lookup.h"
  27. #include "thread.h"
  28. #include "itypes.h"
  29. #include "md.h"
  30.  
  31. object*    ClassFormatError;
  32. object*    LinkageError;
  33. object*    ClassNotFoundException;
  34. object*    NoSuchFieldError;
  35. object*    NoSuchMethodError;
  36. object*    OutOfMemoryError;
  37. object*    UnsatisfiedLinkError;
  38. object*    VirtualMachineError;
  39. object*    ClassCircularityError;
  40. object*    NegativeArraySizeException;
  41. object*    ClassCastException;
  42. object*    IllegalMonitorStateException;
  43. object*    NullPointerException;
  44. object*    ArithmeticException;
  45. object*    ArrayIndexOutOfBoundsException;
  46.  
  47. extern object* exceptionObject;
  48.  
  49. static void dispatchException(throwable*, exceptionFrame*);
  50. static void nullException(EXCEPTIONPROTO);
  51. static void arithmeticException(EXCEPTIONPROTO);
  52.  
  53. object* buildStackTrace(exceptionFrame*);
  54.  
  55. /*
  56.  * Setup the internal exceptions.
  57.  */
  58. void
  59. initExceptions(void)
  60. {
  61. #define    EXCEPTION(s) alloc_object(lookupClass(addString(#s)), true)
  62.  
  63.     ClassFormatError = EXCEPTION(java/lang/ClassFormatError);
  64.     LinkageError = EXCEPTION(java/lang/LinkageError);
  65.     ClassNotFoundException = EXCEPTION(java/lang/ClassNotFoundException);
  66.     NoSuchFieldError = EXCEPTION(java/lang/NoSuchFieldError);
  67.     NoSuchMethodError = EXCEPTION(java/lang/NoSuchMethodError);
  68.     OutOfMemoryError = EXCEPTION(java/lang/OutOfMemoryError);
  69.     UnsatisfiedLinkError = EXCEPTION(java/lang/UnsatisfiedLinkError);
  70.     VirtualMachineError = EXCEPTION(java/lang/VirtualMachineError);
  71.     ClassCircularityError = EXCEPTION(java/lang/ClassCircularityError);
  72.     NegativeArraySizeException = EXCEPTION(java/lang/NegativeArraySizeException);
  73.     ClassCastException = EXCEPTION(java/lang/ClassCastException);
  74.     IllegalMonitorStateException = EXCEPTION(java/lang/IllegalMonitorStateException);
  75.     NullPointerException = EXCEPTION(java/lang/NullPointerException);
  76.     ArithmeticException = EXCEPTION(java/lang/ArithmeticException);
  77.     ArrayIndexOutOfBoundsException = EXCEPTION(java/lang/ArrayIndexOutOfBoundsException);
  78.  
  79.     initClasses();
  80.  
  81. #if !defined(DEBUG)
  82.     /* Catch signal we need to convert to exceptions */
  83. #if defined(SIGSEGV)
  84.     signal(SIGSEGV, (SIG_T)nullException);
  85. #endif
  86. #if defined(SIGBUS)
  87.     signal(SIGBUS, (SIG_T)nullException);
  88. #endif
  89. #if defined(SIGFPE)
  90.     signal(SIGFPE, (SIG_T)arithmeticException);
  91. #endif
  92. #if defined(SIGPIPE)
  93.     signal(SIGPIPE, SIG_IGN);
  94. #endif
  95. #endif
  96. }
  97.  
  98. /*
  99.  * Throw an internal exception.
  100.  */
  101. void
  102. throwException(object* eobj)
  103. {
  104.     ((throwable*)eobj)->backtrace = buildStackTrace(0);
  105.     throwExternalException(eobj);
  106. }
  107.  
  108. /*
  109.  * Throw an external exception.
  110.  */
  111. void
  112. throwExternalException(object* eobj)
  113. {
  114.     exceptionFrame frame;
  115.  
  116.     if (eobj == 0) {
  117.         fprintf(stderr, "Exception thrown on null object ... aborting\n");
  118.         abort();
  119.         exit(1);
  120.     }
  121.     FIRSTFRAME(frame, eobj);
  122.     dispatchException((throwable*)eobj, &frame);
  123. }
  124.  
  125. /*
  126.  * Search for a matching exception.
  127.  */
  128. static
  129. void
  130. dispatchException(throwable* eobj, exceptionFrame* baseframe)
  131. {
  132.     exceptionInfo einfo;
  133.     classes* class;
  134.     exceptionFrame* frame;
  135.     object* str;
  136.     int i;
  137.  
  138.     class = eobj->head.dtable->class;
  139.  
  140.     for (frame = baseframe; FRAMEOKAY(frame); frame = NEXTFRAME(frame)) {
  141.         findExceptionInMethod(PCFRAME(frame), class, &einfo);
  142.         if (einfo.handler != 0) {
  143.             CALL_KAFFE_EXCEPTION(frame, einfo, eobj);
  144.         }
  145.     }
  146.  
  147.     fprintf(stderr, "%s\n", eobj->head.dtable->class->name);
  148.     fflush(stderr);
  149.  
  150.     if (eobj->backtrace != 0) {
  151.         for (i = 0; i < eobj->backtrace->size; i++) {
  152.             str = ((object**)(eobj->backtrace+1))[i];
  153.             if (str != 0) {
  154.                 fprintf(stderr, "%s\n", (char*)(str+1));
  155.             }
  156.         }
  157.     }
  158.     else {
  159.         fprintf(stderr, "\t[no backtrace available]\n");
  160.     }
  161.     exit(1);
  162. }
  163.  
  164. /*
  165.  * Build an array of char[] for the current stack backtrace.
  166.  */
  167. object*
  168. buildStackTrace(exceptionFrame* base)
  169. {
  170.     char buf[100];
  171.     exceptionFrame nframe;
  172.     exceptionFrame* frame;
  173.     methods* meth;
  174.     object* str;
  175.     object* strarray;
  176.     int cnt;
  177.     int i;
  178.     int len;
  179.  
  180.     if (base == 0) { 
  181.         FIRSTFRAME(nframe, base);
  182.         base = &nframe;
  183.     }
  184.  
  185.     /* First count the stack frames */
  186.     cnt = 0;
  187.     for (frame = base; FRAMEOKAY(frame); frame = NEXTFRAME(frame)) {
  188.         cnt++;
  189.     }
  190.  
  191.     /* Build an array of strings */
  192.     strarray = alloc_objectarray(cnt, "[[C");
  193.     assert(strarray != 0);
  194.  
  195.     cnt = 0;
  196.     for (frame = base; FRAMEOKAY(frame); frame = NEXTFRAME(frame)) {
  197.         meth = findMethodFromPC(PCFRAME(frame));
  198.         if (meth != 0) {
  199.             sprintf(buf, "\tat %s.%s(0x%x)",
  200.                 meth->class->name,
  201.                 meth->pair->s1,
  202.                 PCFRAME(frame));
  203.             len = strlen(buf);
  204.             str = alloc_array(len, TYPE_Char);
  205.             assert(str != 0);
  206.             strncpy((char*)(str+1), buf, len);
  207.         }
  208.         else {
  209.             str = 0;
  210.         }
  211.         ((object**)(strarray+1))[cnt] = str;
  212.         cnt++;
  213.     }
  214.     return (strarray);
  215. }
  216.  
  217. /*
  218.  * Null exception - catches bad memory accesses.
  219.  */
  220. static
  221. void
  222. nullException(EXCEPTIONPROTO)
  223. {
  224.     exceptionFrame frame;
  225.  
  226. #if !defined(DEBUG)
  227.     /* Reset signal handler - necessary for SysV, does no harm for BSD */
  228.     signal(sig, (SIG_T)nullException);
  229. #endif
  230.     EXCEPTIONFRAME(frame, ctx);
  231.     ((throwable*)NullPointerException)->backtrace = buildStackTrace(&frame);
  232.     dispatchException((throwable*)NullPointerException, &frame);
  233. }
  234.  
  235. /*
  236.  * Division by zero.
  237.  */
  238. static
  239. void
  240. arithmeticException(EXCEPTIONPROTO)
  241. {
  242.     exceptionFrame frame;
  243.  
  244. #if !defined(DEBUG)
  245.         /* Reset signal handler - necessary for SysV, does no harm for BSD */
  246.         signal(sig, (SIG_T)arithmeticException);
  247. #endif
  248.     EXCEPTIONFRAME(frame, ctx);
  249.     ((throwable*)ArithmeticException)->backtrace = buildStackTrace(&frame);
  250.     dispatchException((throwable*)ArithmeticException, &frame);
  251. }
  252.