Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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