| Index: third_party/libc++/src/exception.cpp
|
| ===================================================================
|
| --- third_party/libc++/src/exception.cpp (revision 0)
|
| +++ third_party/libc++/src/exception.cpp (revision 0)
|
| @@ -0,0 +1,307 @@
|
| +//===------------------------ exception.cpp -------------------------------===//
|
| +//
|
| +// The LLVM Compiler Infrastructure
|
| +//
|
| +// This file is dual licensed under the MIT and the University of Illinois Open
|
| +// Source Licenses. See LICENSE.TXT for details.
|
| +//
|
| +//===----------------------------------------------------------------------===//
|
| +#include <stdlib.h>
|
| +#include <stdio.h>
|
| +
|
| +#include "exception"
|
| +#include "new"
|
| +
|
| +#ifndef __has_include
|
| +#define __has_include(inc) 0
|
| +#endif
|
| +
|
| +#ifdef __APPLE__
|
| + #include <cxxabi.h>
|
| +
|
| + using namespace __cxxabiv1;
|
| + #define HAVE_DEPENDENT_EH_ABI 1
|
| + #ifndef _LIBCPPABI_VERSION
|
| + using namespace __cxxabiapple;
|
| + // On Darwin, there are two STL shared libraries and a lower level ABI
|
| + // shared library. The globals holding the current terminate handler and
|
| + // current unexpected handler are in the ABI library.
|
| + #define __terminate_handler __cxxabiapple::__cxa_terminate_handler
|
| + #define __unexpected_handler __cxxabiapple::__cxa_unexpected_handler
|
| + #endif // _LIBCPPABI_VERSION
|
| +#elif defined(LIBCXXRT) || __has_include(<cxxabi.h>)
|
| + #include <cxxabi.h>
|
| + using namespace __cxxabiv1;
|
| + #if defined(LIBCXXRT) || defined(_LIBCPPABI_VERSION)
|
| + #define HAVE_DEPENDENT_EH_ABI 1
|
| + #endif
|
| +#elif !defined(__GLIBCXX__) // __has_include(<cxxabi.h>)
|
| + static std::terminate_handler __terminate_handler;
|
| + static std::unexpected_handler __unexpected_handler;
|
| +#endif // __has_include(<cxxabi.h>)
|
| +
|
| +namespace std
|
| +{
|
| +
|
| +#if !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__)
|
| +
|
| +// libcxxrt provides implementations of these functions itself.
|
| +unexpected_handler
|
| +set_unexpected(unexpected_handler func) _NOEXCEPT
|
| +{
|
| + return __sync_lock_test_and_set(&__unexpected_handler, func);
|
| +}
|
| +
|
| +unexpected_handler
|
| +get_unexpected() _NOEXCEPT
|
| +{
|
| + return __sync_fetch_and_add(&__unexpected_handler, (unexpected_handler)0);
|
| +}
|
| +
|
| +_LIBCPP_NORETURN
|
| +void
|
| +unexpected()
|
| +{
|
| + (*get_unexpected())();
|
| + // unexpected handler should not return
|
| + terminate();
|
| +}
|
| +
|
| +terminate_handler
|
| +set_terminate(terminate_handler func) _NOEXCEPT
|
| +{
|
| + return __sync_lock_test_and_set(&__terminate_handler, func);
|
| +}
|
| +
|
| +terminate_handler
|
| +get_terminate() _NOEXCEPT
|
| +{
|
| + return __sync_fetch_and_add(&__terminate_handler, (terminate_handler)0);
|
| +}
|
| +
|
| +#ifndef EMSCRIPTEN // We provide this in JS
|
| +_LIBCPP_NORETURN
|
| +void
|
| +terminate() _NOEXCEPT
|
| +{
|
| +#ifndef _LIBCPP_NO_EXCEPTIONS
|
| + try
|
| + {
|
| +#endif // _LIBCPP_NO_EXCEPTIONS
|
| + (*get_terminate())();
|
| + // handler should not return
|
| + printf("terminate_handler unexpectedly returned\n");
|
| + ::abort();
|
| +#ifndef _LIBCPP_NO_EXCEPTIONS
|
| + }
|
| + catch (...)
|
| + {
|
| + // handler should not throw exception
|
| + printf("terminate_handler unexpectedly threw an exception\n");
|
| + ::abort();
|
| + }
|
| +#endif // _LIBCPP_NO_EXCEPTIONS
|
| +}
|
| +#endif // !EMSCRIPTEN
|
| +#endif // !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION)
|
| +
|
| +#if !defined(LIBCXXRT) && !defined(__GLIBCXX__) && !defined(EMSCRIPTEN)
|
| +bool uncaught_exception() _NOEXCEPT
|
| +{
|
| +#if defined(__APPLE__) || defined(_LIBCPPABI_VERSION)
|
| + // on Darwin, there is a helper function so __cxa_get_globals is private
|
| + return __cxa_uncaught_exception();
|
| +#else // __APPLE__
|
| +# if defined(_MSC_VER) && ! defined(__clang__)
|
| + _LIBCPP_WARNING("uncaught_exception not yet implemented")
|
| +# else
|
| +# warning uncaught_exception not yet implemented
|
| +# endif
|
| + printf("uncaught_exception not yet implemented\n");
|
| + ::abort();
|
| +#endif // __APPLE__
|
| +}
|
| +
|
| +
|
| +#ifndef _LIBCPPABI_VERSION
|
| +
|
| +exception::~exception() _NOEXCEPT
|
| +{
|
| +}
|
| +
|
| +const char* exception::what() const _NOEXCEPT
|
| +{
|
| + return "std::exception";
|
| +}
|
| +
|
| +#endif // _LIBCPPABI_VERSION
|
| +#endif //LIBCXXRT
|
| +#if !defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__)
|
| +
|
| +bad_exception::~bad_exception() _NOEXCEPT
|
| +{
|
| +}
|
| +
|
| +const char* bad_exception::what() const _NOEXCEPT
|
| +{
|
| + return "std::bad_exception";
|
| +}
|
| +
|
| +#endif
|
| +
|
| +#if defined(__GLIBCXX__)
|
| +
|
| +// libsupc++ does not implement the dependent EH ABI and the functionality
|
| +// it uses to implement std::exception_ptr (which it declares as an alias of
|
| +// std::__exception_ptr::exception_ptr) is not directly exported to clients. So
|
| +// we have little choice but to hijack std::__exception_ptr::exception_ptr's
|
| +// (which fortunately has the same layout as our std::exception_ptr) copy
|
| +// constructor, assignment operator and destructor (which are part of its
|
| +// stable ABI), and its rethrow_exception(std::__exception_ptr::exception_ptr)
|
| +// function.
|
| +
|
| +namespace __exception_ptr
|
| +{
|
| +
|
| +struct exception_ptr
|
| +{
|
| + void* __ptr_;
|
| +
|
| + exception_ptr(const exception_ptr&) _NOEXCEPT;
|
| + exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
|
| + ~exception_ptr() _NOEXCEPT;
|
| +};
|
| +
|
| +}
|
| +
|
| +_LIBCPP_NORETURN void rethrow_exception(__exception_ptr::exception_ptr);
|
| +
|
| +#endif
|
| +
|
| +exception_ptr::~exception_ptr() _NOEXCEPT
|
| +{
|
| +#if HAVE_DEPENDENT_EH_ABI
|
| + __cxa_decrement_exception_refcount(__ptr_);
|
| +#elif defined(__GLIBCXX__)
|
| + reinterpret_cast<__exception_ptr::exception_ptr*>(this)->~exception_ptr();
|
| +#else
|
| +# if defined(_MSC_VER) && ! defined(__clang__)
|
| + _LIBCPP_WARNING("exception_ptr not yet implemented")
|
| +# else
|
| +# warning exception_ptr not yet implemented
|
| +# endif
|
| + printf("exception_ptr not yet implemented\n");
|
| + ::abort();
|
| +#endif
|
| +}
|
| +
|
| +exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT
|
| + : __ptr_(other.__ptr_)
|
| +{
|
| +#if HAVE_DEPENDENT_EH_ABI
|
| + __cxa_increment_exception_refcount(__ptr_);
|
| +#elif defined(__GLIBCXX__)
|
| + new (reinterpret_cast<void*>(this)) __exception_ptr::exception_ptr(
|
| + reinterpret_cast<const __exception_ptr::exception_ptr&>(other));
|
| +#else
|
| +# if defined(_MSC_VER) && ! defined(__clang__)
|
| + _LIBCPP_WARNING("exception_ptr not yet implemented")
|
| +# else
|
| +# warning exception_ptr not yet implemented
|
| +# endif
|
| + printf("exception_ptr not yet implemented\n");
|
| + ::abort();
|
| +#endif
|
| +}
|
| +
|
| +exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT
|
| +{
|
| +#if HAVE_DEPENDENT_EH_ABI
|
| + if (__ptr_ != other.__ptr_)
|
| + {
|
| + __cxa_increment_exception_refcount(other.__ptr_);
|
| + __cxa_decrement_exception_refcount(__ptr_);
|
| + __ptr_ = other.__ptr_;
|
| + }
|
| + return *this;
|
| +#elif defined(__GLIBCXX__)
|
| + *reinterpret_cast<__exception_ptr::exception_ptr*>(this) =
|
| + reinterpret_cast<const __exception_ptr::exception_ptr&>(other);
|
| + return *this;
|
| +#else
|
| +# if defined(_MSC_VER) && ! defined(__clang__)
|
| + _LIBCPP_WARNING("exception_ptr not yet implemented")
|
| +# else
|
| +# warning exception_ptr not yet implemented
|
| +# endif
|
| + printf("exception_ptr not yet implemented\n");
|
| + ::abort();
|
| +#endif
|
| +}
|
| +
|
| +nested_exception::nested_exception() _NOEXCEPT
|
| + : __ptr_(current_exception())
|
| +{
|
| +}
|
| +
|
| +#if !defined(__GLIBCXX__)
|
| +
|
| +nested_exception::~nested_exception() _NOEXCEPT
|
| +{
|
| +}
|
| +
|
| +#endif
|
| +
|
| +_LIBCPP_NORETURN
|
| +void
|
| +nested_exception::rethrow_nested() const
|
| +{
|
| + if (__ptr_ == nullptr)
|
| + terminate();
|
| + rethrow_exception(__ptr_);
|
| +}
|
| +
|
| +#if !defined(__GLIBCXX__)
|
| +
|
| +exception_ptr current_exception() _NOEXCEPT
|
| +{
|
| +#if HAVE_DEPENDENT_EH_ABI
|
| + // be nicer if there was a constructor that took a ptr, then
|
| + // this whole function would be just:
|
| + // return exception_ptr(__cxa_current_primary_exception());
|
| + exception_ptr ptr;
|
| + ptr.__ptr_ = __cxa_current_primary_exception();
|
| + return ptr;
|
| +#else
|
| +# if defined(_MSC_VER) && ! defined(__clang__)
|
| + _LIBCPP_WARNING( "exception_ptr not yet implemented" )
|
| +# else
|
| +# warning exception_ptr not yet implemented
|
| +# endif
|
| + printf("exception_ptr not yet implemented\n");
|
| + ::abort();
|
| +#endif
|
| +}
|
| +
|
| +#endif // !__GLIBCXX__
|
| +
|
| +_LIBCPP_NORETURN
|
| +void rethrow_exception(exception_ptr p)
|
| +{
|
| +#if HAVE_DEPENDENT_EH_ABI
|
| + __cxa_rethrow_primary_exception(p.__ptr_);
|
| + // if p.__ptr_ is NULL, above returns so we terminate
|
| + terminate();
|
| +#elif defined(__GLIBCXX__)
|
| + rethrow_exception(reinterpret_cast<__exception_ptr::exception_ptr&>(p));
|
| +#else
|
| +# if defined(_MSC_VER) && ! defined(__clang__)
|
| + _LIBCPP_WARNING("exception_ptr not yet implemented")
|
| +# else
|
| +# warning exception_ptr not yet implemented
|
| +# endif
|
| + printf("exception_ptr not yet implemented\n");
|
| + ::abort();
|
| +#endif
|
| +}
|
| +} // std
|
|
|
| Property changes on: third_party/libc++/src/exception.cpp
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|