Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // -*- C++ -*- Exception handling routines for catching.
  2. // Copyright (C) 2001-2015 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 <cstdlib>
  26. #include "unwind-cxx.h"
  27.  
  28. using namespace __cxxabiv1;
  29.  
  30. extern "C" void *
  31. __cxxabiv1::__cxa_get_exception_ptr(void *exc_obj_in) _GLIBCXX_NOTHROW
  32. {
  33.   _Unwind_Exception *exceptionObject
  34.     = reinterpret_cast <_Unwind_Exception *>(exc_obj_in);
  35.  
  36.   return __gxx_caught_object(exceptionObject);
  37. }
  38.  
  39. extern "C" void *
  40. __cxxabiv1::__cxa_begin_catch (void *exc_obj_in) _GLIBCXX_NOTHROW
  41. {
  42.   _Unwind_Exception *exceptionObject
  43.     = reinterpret_cast <_Unwind_Exception *>(exc_obj_in);
  44.   __cxa_eh_globals *globals = __cxa_get_globals ();
  45.   __cxa_exception *prev = globals->caughtExceptions;
  46.   __cxa_exception *header = __get_exception_header_from_ue (exceptionObject);
  47.   void* objectp;
  48.  
  49.   // Foreign exceptions can't be stacked here.  If the exception stack is
  50.   // empty, then fine.  Otherwise we really have no choice but to terminate.
  51.   // Note that this use of "header" is a lie.  It's fine so long as we only
  52.   // examine header->unwindHeader though.
  53.   if (!__is_gxx_exception_class(header->unwindHeader.exception_class))
  54.     {
  55.       if (prev != 0)
  56.         std::terminate ();
  57.  
  58.       // Remember for end_catch and rethrow.
  59.       globals->caughtExceptions = header;
  60.  
  61.       // ??? No sensible value to return; we don't know what the
  62.       // object is, much less where it is in relation to the header.
  63.       return 0;
  64.     }
  65.  
  66.   int count = header->handlerCount;
  67.   // Count is less than zero if this exception was rethrown from an
  68.   // immediately enclosing region.
  69.   if (count < 0)
  70.     count = -count + 1;
  71.   else
  72.     count += 1;
  73.   header->handlerCount = count;
  74.   globals->uncaughtExceptions -= 1;
  75.  
  76.   if (header != prev)
  77.     {
  78.       header->nextException = prev;
  79.       globals->caughtExceptions = header;
  80.     }
  81.  
  82.   objectp = __gxx_caught_object(exceptionObject);
  83.  
  84.   PROBE2 (catch, objectp, header->exceptionType);
  85.  
  86. #ifdef __ARM_EABI_UNWINDER__
  87.   _Unwind_Complete(exceptionObject);
  88. #endif
  89.   return objectp;
  90. }
  91.  
  92.  
  93. extern "C" void
  94. __cxxabiv1::__cxa_end_catch ()
  95. {
  96.   __cxa_eh_globals *globals = __cxa_get_globals_fast ();
  97.   __cxa_exception *header = globals->caughtExceptions;
  98.  
  99.   // A rethrow of a foreign exception will be removed from the
  100.   // the exception stack immediately by __cxa_rethrow.
  101.   if (!header)
  102.     return;
  103.  
  104.   // A foreign exception couldn't have been stacked (see above),
  105.   // so by definition processing must be complete.
  106.   if (!__is_gxx_exception_class(header->unwindHeader.exception_class))
  107.     {
  108.       globals->caughtExceptions = 0;
  109.       _Unwind_DeleteException (&header->unwindHeader);
  110.       return;
  111.     }
  112.  
  113.   int count = header->handlerCount;
  114.   if (count < 0)
  115.     {
  116.       // This exception was rethrown.  Decrement the (inverted) catch
  117.       // count and remove it from the chain when it reaches zero.
  118.       if (++count == 0)
  119.         globals->caughtExceptions = header->nextException;
  120.     }
  121.   else if (--count == 0)
  122.     {
  123.       // Handling for this exception is complete.  Destroy the object.
  124.       globals->caughtExceptions = header->nextException;
  125.       _Unwind_DeleteException (&header->unwindHeader);
  126.       return;
  127.     }
  128.   else if (count < 0)
  129.     // A bug in the exception handling library or compiler.
  130.     std::terminate ();
  131.  
  132.   header->handlerCount = count;
  133. }
  134.  
  135.  
  136. bool
  137. std::uncaught_exception() throw()
  138. {
  139.   __cxa_eh_globals *globals = __cxa_get_globals ();
  140.   return globals->uncaughtExceptions != 0;
  141. }
  142.