OSDN Git Service

PR java/8473:
[pf3gnuchains/gcc-fork.git] / libjava / exception.cc
index 41f7676..088d482 100644 (file)
@@ -1,6 +1,6 @@
 // Functions for Exception Support for Java.
 
-/* Copyright (C) 1998, 1999, 2001  Free Software Foundation
+/* Copyright (C) 1998, 1999, 2001, 2002  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -15,25 +15,25 @@ details.  */
 
 #include <java/lang/Class.h>
 #include <java/lang/NullPointerException.h>
+#include <gnu/gcj/runtime/StackTrace.h> 
+#include <gnu/gcj/runtime/MethodRef.h> 
+#include <gnu/gcj/RawData.h> 
 #include <gcj/cni.h>
 #include <jvm.h>
 
-#include "unwind.h"
-
-\f
-// More nastiness: the GC wants to define TRUE and FALSE.  We don't
-// need the Java definitions (themselves a hack), so we undefine them.
-#undef TRUE
-#undef FALSE
-
-extern "C"
+// unwind-pe.h uses std::abort(), but sometimes we compile libjava
+// without libstdc++-v3. The following hack forces it to use
+// stdlib.h's abort().
+namespace std
 {
-#include <gc_priv.h>
-#include <gc_mark.h>
-#include <include/gc_gcj.h>
-};
+  static __attribute__ ((__noreturn__)) void
+  abort ()
+  {
+    ::abort ();
+  }
+}
+#include "unwind.h"
 
-\f
 struct alignment_test_struct
 {
   char space;
@@ -84,9 +84,8 @@ get_exception_header_from_ue (_Unwind_Exception *exc)
 extern "C" void
 _Jv_Throw (jthrowable value)
 {
-  /* FIXME: Use the proper API to the collector.  */
   java_exception_header *xh
-    = static_cast<java_exception_header *>(GC_malloc (sizeof (*xh)));
+    = static_cast<java_exception_header *>(_Jv_AllocRawObj (sizeof (*xh)));
 
   if (value == NULL)
     value = new java::lang::NullPointerException ();
@@ -104,186 +103,18 @@ _Jv_Throw (jthrowable value)
   code = _Unwind_RaiseException (&xh->unwindHeader);
 #endif
 
-  /* FIXME: If code == _URC_END_OF_STACK, then we reached top of
-     stack without finding a handler for the exception.  I seem to
-     recall that Java has specific rules to handle this. 
-
-     If code is something else, we encountered some sort of heinous
-     lossage, from which we could not recover.  As is the way of such
-     things we'll almost certainly have crashed before now, rather
-     than actually being able to diagnose the problem.  */
-  abort ();
+  /* If code == _URC_END_OF_STACK, then we reached top of stack without
+     finding a handler for the exception.  Since each thread is run in
+     a try/catch, this oughtn't happen.  If code is something else, we
+     encountered some sort of heinous lossage from which we could not
+     recover.  As is the way of such things, almost certainly we will have
+     crashed before now, rather than actually being able to diagnose the
+     problem.  */
+  abort();
 }
 
 \f
-// ??? These ought to go somewhere else dwarf2 or dwarf2eh related.
-
-// Pointer encodings.
-#define DW_EH_PE_absptr         0x00
-#define DW_EH_PE_omit           0xff
-
-#define DW_EH_PE_uleb128        0x01
-#define DW_EH_PE_udata2         0x02
-#define DW_EH_PE_udata4         0x03
-#define DW_EH_PE_udata8         0x04
-#define DW_EH_PE_sleb128        0x09
-#define DW_EH_PE_sdata2         0x0A
-#define DW_EH_PE_sdata4         0x0B
-#define DW_EH_PE_sdata8         0x0C
-#define DW_EH_PE_signed         0x08
-
-#define DW_EH_PE_pcrel          0x10
-#define DW_EH_PE_textrel        0x20
-#define DW_EH_PE_datarel        0x30
-#define DW_EH_PE_funcrel        0x40
-
-static unsigned int
-size_of_encoded_value (unsigned char encoding)
-{
-  switch (encoding & 0x07)
-    {
-    case DW_EH_PE_absptr:
-      return sizeof (void *);
-    case DW_EH_PE_udata2:
-      return 2;
-    case DW_EH_PE_udata4:
-      return 4;
-    case DW_EH_PE_udata8:
-      return 8;
-    }
-  abort ();
-}
-
-static const unsigned char *
-read_encoded_value (_Unwind_Context *context, unsigned char encoding,
-                   const unsigned char *p, _Unwind_Ptr *val)
-{
-  union unaligned
-    {
-      void *ptr;
-      unsigned u2 __attribute__ ((mode (HI)));
-      unsigned u4 __attribute__ ((mode (SI)));
-      unsigned u8 __attribute__ ((mode (DI)));
-      signed s2 __attribute__ ((mode (HI)));
-      signed s4 __attribute__ ((mode (SI)));
-      signed s8 __attribute__ ((mode (DI)));
-    } __attribute__((__packed__));
-
-  union unaligned *u = (union unaligned *) p;
-  _Unwind_Ptr result;
-
-  switch (encoding & 0x0f)
-    {
-    case DW_EH_PE_absptr:
-      result = (_Unwind_Ptr) u->ptr;
-      p += sizeof (void *);
-      break;
-
-    case DW_EH_PE_uleb128:
-      {
-       unsigned int shift = 0;
-       unsigned char byte;
-
-       result = 0;
-       do
-         {
-           byte = *p++;
-           result |= (_Unwind_Ptr)(byte & 0x7f) << shift;
-           shift += 7;
-         }
-       while (byte & 0x80);
-      }
-      break;
-
-    case DW_EH_PE_sleb128:
-      {
-       unsigned int shift = 0;
-       unsigned char byte;
-
-       result = 0;
-       do
-         {
-           byte = *p++;
-           result |= (_Unwind_Ptr)(byte & 0x7f) << shift;
-           shift += 7;
-         }
-       while (byte & 0x80);
-
-       if (shift < 8 * sizeof(result) && (byte & 0x40) != 0)
-         result |= -(1L << shift);
-      }
-      break;
-
-    case DW_EH_PE_udata2:
-      result = u->u2;
-      p += 2;
-      break;
-    case DW_EH_PE_udata4:
-      result = u->u4;
-      p += 4;
-      break;
-    case DW_EH_PE_udata8:
-      result = u->u8;
-      p += 8;
-      break;
-
-    case DW_EH_PE_sdata2:
-      result = u->s2;
-      p += 2;
-      break;
-    case DW_EH_PE_sdata4:
-      result = u->s4;
-      p += 4;
-      break;
-    case DW_EH_PE_sdata8:
-      result = u->s8;
-      p += 8;
-      break;
-
-    default:
-      abort ();
-    }
-
-  if (result != 0)
-    switch (encoding & 0xf0)
-      {
-      case DW_EH_PE_absptr:
-       break;
-
-      case DW_EH_PE_pcrel:
-       // Define as relative to the beginning of the pointer.
-       result += (_Unwind_Ptr) u;
-       break;
-
-      case DW_EH_PE_textrel:
-      case DW_EH_PE_datarel:
-       // FIXME.
-       abort ();
-
-      case DW_EH_PE_funcrel:
-       result += _Unwind_GetRegionStart (context);
-       break;
-
-      default:
-       abort ();
-      }
-
-  *val = result;
-  return p;
-}
-
-static inline const unsigned char *
-read_uleb128 (const unsigned char *p, _Unwind_Ptr *val)
-{
-  return read_encoded_value (0, DW_EH_PE_uleb128, p, val);
-}
-
-static inline const unsigned char *
-read_sleb128 (const unsigned char *p, _Unwind_Ptr *val)
-{
-  return read_encoded_value (0, DW_EH_PE_sleb128, p, val);
-}
-
+#include "unwind-pe.h"
 \f
 struct lsda_header_info
 {
@@ -299,7 +130,7 @@ static const unsigned char *
 parse_lsda_header (_Unwind_Context *context, const unsigned char *p,
                   lsda_header_info *info)
 {
-  _Unwind_Ptr tmp;
+  _Unwind_Word tmp;
   unsigned char lpstart_encoding;
 
   info->Start = (context ? _Unwind_GetRegionStart (context) : 0);
@@ -330,7 +161,7 @@ parse_lsda_header (_Unwind_Context *context, const unsigned char *p,
   return p;
 }
 
-static jclass
+static void **
 get_ttype_entry (_Unwind_Context *context, lsda_header_info *info, long i)
 {
   _Unwind_Ptr ptr;
@@ -338,7 +169,7 @@ get_ttype_entry (_Unwind_Context *context, lsda_header_info *info, long i)
   i *= size_of_encoded_value (info->ttype_encoding);
   read_encoded_value (context, info->ttype_encoding, info->TType - i, &ptr);
 
-  return reinterpret_cast<jclass>(ptr);
+  return reinterpret_cast<void **>(ptr);
 }
 
 
@@ -415,7 +246,7 @@ PERSONALITY_FUNCTION (int version,
     return _URC_CONTINUE_UNWIND;
   else
     {
-      _Unwind_Ptr cs_lp, cs_action;
+      _Unwind_Word cs_lp, cs_action;
       do
        {
          p = read_uleb128 (p, &cs_lp);
@@ -434,7 +265,8 @@ PERSONALITY_FUNCTION (int version,
   // Search the call-site table for the action associated with this IP.
   while (p < info.action_table)
     {
-      _Unwind_Ptr cs_start, cs_len, cs_lp, cs_action;
+      _Unwind_Ptr cs_start, cs_len, cs_lp;
+      _Unwind_Word cs_action;
 
       // Note that all call-site encodings are "absolute" displacements.
       p = read_encoded_value (0, info.call_site_encoding, p, &cs_start);
@@ -480,15 +312,13 @@ PERSONALITY_FUNCTION (int version,
   else
     {
       // Otherwise we have a catch handler.
-      signed long ar_filter, ar_disp;
+      _Unwind_Sword ar_filter, ar_disp;
 
       while (1)
        {
-         _Unwind_Ptr tmp;
-
          p = action_record;
-         p = read_sleb128 (p, &tmp); ar_filter = tmp;
-         read_sleb128 (p, &tmp); ar_disp = tmp;
+         p = read_sleb128 (p, &ar_filter);
+         read_sleb128 (p, &ar_disp);
 
          if (ar_filter == 0)
            {
@@ -506,12 +336,14 @@ PERSONALITY_FUNCTION (int version,
            {
              // Positive filter values are handlers.
 
-             jclass catch_type = get_ttype_entry (context, &info, ar_filter);
+             void **catch_word = get_ttype_entry (context, &info, ar_filter);
+             jclass catch_type = (jclass)*catch_word;
 
-             // The catch_type is either a (java::lang::Class*) or
-             // is one more than a (Utf8Const*).
-             if ((size_t)catch_type & 1)
-               catch_type = _Jv_FindClass ((Utf8Const*)catch_type - 1, NULL);
+             // FIXME: This line is a kludge to work around exception
+             // handlers written in C++, which don't yet use indirect
+             // dispatch.
+             if (catch_type == *(void **)&java::lang::Class::class$)
+               catch_type = (jclass)catch_word;
 
              if (_Jv_IsInstanceOf (xh->value, catch_type))
                {