OSDN Git Service

gcc/
[pf3gnuchains/gcc-fork.git] / libjava / exception.cc
index 9647d44..65bc4ed 100644 (file)
@@ -1,6 +1,6 @@
 // Functions for Exception Support for Java.
 
-/* Copyright (C) 1998, 1999, 2001, 2002  Free Software Foundation
+/* Copyright (C) 1998, 1999, 2001, 2002, 2006  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -15,8 +15,6 @@ 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>
@@ -161,7 +159,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;
@@ -169,7 +167,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);
 }
 
 
@@ -199,6 +197,7 @@ PERSONALITY_FUNCTION (int version,
   int handler_switch_value;
   bool saw_cleanup;
   bool saw_handler;
+  int ip_before_insn = 0;
 
 
   // Interface version check.
@@ -214,10 +213,10 @@ PERSONALITY_FUNCTION (int version,
       goto install_context;
     }
 
-  // FIXME: In Phase 1, record _Unwind_GetIP in xh->obj as a part of
+  // FIXME: In Phase 1, record _Unwind_GetIPInfo in xh->obj as a part of
   // the stack trace for this exception.  This will only collect Java
   // frames, but perhaps that is acceptable.
-  // FIXME2: _Unwind_GetIP is nonsensical for SJLJ, being a call-site
+  // FIXME2: _Unwind_GetIPInfo is nonsensical for SJLJ, being a call-site
   // index instead of a PC value.  We could perhaps arrange for
   // _Unwind_GetRegionStart to return context->fc->jbuf[1], which
   // is the address of the handler label for __builtin_longjmp, but
@@ -232,7 +231,9 @@ PERSONALITY_FUNCTION (int version,
 
   // Parse the LSDA header.
   p = parse_lsda_header (context, language_specific_data, &info);
-  ip = _Unwind_GetIP (context) - 1;
+  ip = _Unwind_GetIPInfo (context, &ip_before_insn);
+  if (! ip_before_insn)
+    --ip;
   landing_pad = 0;
   action_record = 0;
   handler_switch_value = 0;
@@ -336,23 +337,15 @@ 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;
+
+             // 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;
 
-             typedef struct {
-               int __attribute__ ((mode (pointer))) dummy; 
-               Utf8Const *utf8;
-             } utf8_hdr;
-             utf8_hdr *p = (utf8_hdr *)catch_type;
-             if (p->dummy == -1)
-               {
-                 using namespace gnu::gcj::runtime;
-                 java::lang::Class *klass 
-                   = StackTrace::getClass ((gnu::gcj::RawData *)ip);
-                 java::lang::ClassLoader *loader 
-                   = klass ? klass->getClassLoaderInternal () : NULL;
-                 catch_type = _Jv_FindClass (p->utf8, loader);
-               }
-             
              if (_Jv_IsInstanceOf (xh->value, catch_type))
                {
                  handler_switch_value = ar_filter;