X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=libjava%2Fexception.cc;h=4875dfde52f55652a83af73087483d0682653e61;hp=16bbb9fa114be47d167dca9f72fcf005ebe3996c;hb=c6d4f471fef8487f5f4f5a30cd99f4bde182514b;hpb=44fff91ac6a44e9e37b45e3074dc6180dc647a9c diff --git a/libjava/exception.cc b/libjava/exception.cc index 16bbb9fa114..4875dfde52f 100644 --- a/libjava/exception.cc +++ b/libjava/exception.cc @@ -1,6 +1,6 @@ // Functions for Exception Support for Java. -/* Copyright (C) 1998, 1999, 2001 Free Software Foundation +/* Copyright (C) 1998, 1999, 2001, 2002, 2006 Free Software Foundation This file is part of libgcj. @@ -11,18 +11,27 @@ details. */ #include #include -#include +#include #include #include +#include #include #include +// 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 +{ + static __attribute__ ((__noreturn__)) void + abort () + { + ::abort (); + } +} #include "unwind.h" -#include - - struct alignment_test_struct { char space; @@ -73,9 +82,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(GC_malloc (sizeof (*xh))); + = static_cast(_Jv_AllocRawObj (sizeof (*xh))); if (value == NULL) value = new java::lang::NullPointerException (); @@ -100,7 +108,7 @@ _Jv_Throw (jthrowable value) 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. */ - std::abort (); + abort(); } @@ -120,7 +128,7 @@ static const unsigned char * parse_lsda_header (_Unwind_Context *context, const unsigned char *p, lsda_header_info *info) { - _Unwind_Ptr tmp; + _uleb128_t tmp; unsigned char lpstart_encoding; info->Start = (context ? _Unwind_GetRegionStart (context) : 0); @@ -151,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; @@ -159,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(ptr); + return reinterpret_cast(ptr); } @@ -189,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. @@ -204,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 @@ -222,7 +231,13 @@ PERSONALITY_FUNCTION (int version, // Parse the LSDA header. p = parse_lsda_header (context, language_specific_data, &info); +#ifdef HAVE_GETIPINFO + ip = _Unwind_GetIPInfo (context, &ip_before_insn); + if (! ip_before_insn) + --ip; +#else ip = _Unwind_GetIP (context) - 1; +#endif landing_pad = 0; action_record = 0; handler_switch_value = 0; @@ -236,7 +251,7 @@ PERSONALITY_FUNCTION (int version, return _URC_CONTINUE_UNWIND; else { - _Unwind_Ptr cs_lp, cs_action; + _uleb128_t cs_lp, cs_action; do { p = read_uleb128 (p, &cs_lp); @@ -255,7 +270,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; + _uleb128_t cs_action; // Note that all call-site encodings are "absolute" displacements. p = read_encoded_value (0, info.call_site_encoding, p, &cs_start); @@ -301,15 +317,13 @@ PERSONALITY_FUNCTION (int version, else { // Otherwise we have a catch handler. - signed long ar_filter, ar_disp; + _sleb128_t 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) { @@ -327,12 +341,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)) { @@ -348,7 +364,7 @@ PERSONALITY_FUNCTION (int version, // ??? Perhaps better to make them an index into a table // of null-terminated strings instead of playing games // with Utf8Const+1 as above. - std::abort (); + abort (); } if (ar_disp == 0)