Subversion Repositories Kolibri OS

Rev

Rev 5134 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. // -*- C++ -*- Exception handling routines for throwing.
  2. // Copyright (C) 2001-2013 Free Software Foundation, Inc.
  3. //
  4. // This file is part of GCC.
  5. //
  6. // GCC is free software; you can redistribute it and/or modify
  7. // it under the terms of the GNU General Public License as published by
  8. // the Free Software Foundation; either version 3, or (at your option)
  9. // any later version.
  10. //
  11. // GCC is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. // GNU General Public License for more details.
  15. //
  16. // Under Section 7 of GPL version 3, you are granted additional
  17. // permissions described in the GCC Runtime Library Exception, version
  18. // 3.1, as published by the Free Software Foundation.
  19.  
  20. // You should have received a copy of the GNU General Public License and
  21. // a copy of the GCC Runtime Library Exception along with this program;
  22. // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  23. // <http://www.gnu.org/licenses/>.
  24.  
  25. #include <bits/c++config.h>
  26. #include "unwind-cxx.h"
  27.  
  28. using namespace __cxxabiv1;
  29.  
  30.  
  31. static void
  32. __gxx_exception_cleanup (_Unwind_Reason_Code code, _Unwind_Exception *exc)
  33. {
  34.   // This cleanup is set only for primaries.
  35.   __cxa_refcounted_exception *header
  36.     = __get_refcounted_exception_header_from_ue (exc);
  37.  
  38.   // We only want to be called through _Unwind_DeleteException.
  39.   // _Unwind_DeleteException in the HP-UX IA64 libunwind library
  40.   // returns _URC_NO_REASON and not _URC_FOREIGN_EXCEPTION_CAUGHT
  41.   // like the GCC _Unwind_DeleteException function does.
  42.   if (code != _URC_FOREIGN_EXCEPTION_CAUGHT && code != _URC_NO_REASON)
  43.     __terminate (header->exc.terminateHandler);
  44.  
  45. #if ATOMIC_INT_LOCK_FREE > 1
  46.   if (__atomic_sub_fetch (&header->referenceCount, 1, __ATOMIC_ACQ_REL) == 0)
  47.     {
  48. #endif
  49.       if (header->exc.exceptionDestructor)
  50.         header->exc.exceptionDestructor (header + 1);
  51.  
  52.       __cxa_free_exception (header + 1);
  53. #if ATOMIC_INT_LOCK_FREE > 1
  54.     }
  55. #endif
  56. }
  57.  
  58.  
  59. extern "C" void
  60. __cxxabiv1::__cxa_throw (void *obj, std::type_info *tinfo,
  61.                          void (_GLIBCXX_CDTOR_CALLABI *dest) (void *))
  62. {
  63.   PROBE2 (throw, obj, tinfo);
  64.  
  65.   // Definitely a primary.
  66.   __cxa_refcounted_exception *header
  67.     = __get_refcounted_exception_header_from_obj (obj);
  68.   header->referenceCount = 1;
  69.   header->exc.exceptionType = tinfo;
  70.   header->exc.exceptionDestructor = dest;
  71.   header->exc.unexpectedHandler = __unexpected_handler;
  72.   header->exc.terminateHandler = __terminate_handler;
  73.   __GXX_INIT_PRIMARY_EXCEPTION_CLASS(header->exc.unwindHeader.exception_class);
  74.   header->exc.unwindHeader.exception_cleanup = __gxx_exception_cleanup;
  75.  
  76. #ifdef _GLIBCXX_SJLJ_EXCEPTIONS
  77.   _Unwind_SjLj_RaiseException (&header->exc.unwindHeader);
  78. #else
  79.   _Unwind_RaiseException (&header->exc.unwindHeader);
  80. #endif
  81.  
  82.   // Some sort of unwinding error.  Note that terminate is a handler.
  83.   __cxa_begin_catch (&header->exc.unwindHeader);
  84.   std::terminate ();
  85. }
  86.  
  87. extern "C" void
  88. __cxxabiv1::__cxa_rethrow ()
  89. {
  90.   __cxa_eh_globals *globals = __cxa_get_globals ();
  91.   __cxa_exception *header = globals->caughtExceptions;
  92.  
  93.   globals->uncaughtExceptions += 1;
  94.  
  95.   // Watch for luser rethrowing with no active exception.
  96.   if (header)
  97.     {
  98.       // Tell __cxa_end_catch this is a rethrow.
  99.       if (!__is_gxx_exception_class(header->unwindHeader.exception_class))
  100.         globals->caughtExceptions = 0;
  101.       else
  102.         {
  103.           header->handlerCount = -header->handlerCount;
  104.           // Only notify probe for C++ exceptions.
  105.           PROBE2 (rethrow, __get_object_from_ambiguous_exception(header),
  106.                   header->exceptionType);
  107.         }
  108.  
  109. #ifdef _GLIBCXX_SJLJ_EXCEPTIONS
  110.       _Unwind_SjLj_Resume_or_Rethrow (&header->unwindHeader);
  111. #else
  112. #if defined(_LIBUNWIND_STD_ABI)
  113.       _Unwind_RaiseException (&header->unwindHeader);
  114. #else
  115.       _Unwind_Resume_or_Rethrow (&header->unwindHeader);
  116. #endif
  117. #endif
  118.  
  119.       // Some sort of unwinding error.  Note that terminate is a handler.
  120.       __cxa_begin_catch (&header->unwindHeader);
  121.     }
  122.   std::terminate ();
  123. }
  124.