diff options
Diffstat (limited to 'libcxx/src')
-rw-r--r-- | libcxx/src/exception.cpp | 171 | ||||
-rw-r--r-- | libcxx/src/new.cpp | 127 | ||||
-rw-r--r-- | libcxx/src/typeinfo.cpp | 41 |
3 files changed, 339 insertions, 0 deletions
diff --git a/libcxx/src/exception.cpp b/libcxx/src/exception.cpp new file mode 100644 index 00000000000..336527df275 --- /dev/null +++ b/libcxx/src/exception.cpp @@ -0,0 +1,171 @@ +//===------------------------ exception.cpp -------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include <stdlib.h> + +#include "exception" + +#if __APPLE__ + #include <cxxabi.h> + using namespace __cxxabiv1; + // On Darwin, there are two STL shared libraries and a lower level ABI + // shared libray. 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 +#else + static std::terminate_handler __terminate_handler; + static std::unexpected_handler __unexpected_handler; +#endif + + + +std::unexpected_handler +std::set_unexpected(std::unexpected_handler func) throw() +{ + std::terminate_handler old = __unexpected_handler; + __unexpected_handler = func; + return old; +} + +void +std::unexpected() +{ + (*__unexpected_handler)(); + // unexpected handler should not return + std::terminate(); +} + + +std::terminate_handler +std::set_terminate(std::terminate_handler func) throw() +{ + std::terminate_handler old = __terminate_handler; + __terminate_handler = func; + return old; +} + + +void +std::terminate() +{ + try { + (*__terminate_handler)(); + // handler should not return + ::abort (); + } + catch (...) { + // handler should not throw exception + ::abort (); + } +} + + +bool std::uncaught_exception() throw() +{ +#if __APPLE__ + // on Darwin, there is a helper function so __cxa_get_globals is private + return __cxxabiapple::__cxa_uncaught_exception(); +#else + __cxa_eh_globals * globals = __cxa_get_globals(); + return (globals->uncaughtExceptions != 0); +#endif +} + + +namespace std +{ + + +exception::~exception() throw() +{ +} + +bad_exception::~bad_exception() throw() +{ +} + +const char* exception::what() const throw() +{ + return "std::exception"; +} + +const char* bad_exception::what() const throw() +{ + return "std::bad_exception"; +} + + + +exception_ptr::~exception_ptr() +{ +#if __APPLE__ + __cxxabiapple::__cxa_decrement_exception_refcount(__ptr_); +#else + #warning exception_ptr not yet implemented + ::abort(); +#endif +} + +exception_ptr::exception_ptr(const exception_ptr& other) + : __ptr_(other.__ptr_) +{ +#if __APPLE__ + __cxxabiapple::__cxa_increment_exception_refcount(__ptr_); +#else + #warning exception_ptr not yet implemented + ::abort(); +#endif +} + +exception_ptr& exception_ptr::operator=(const exception_ptr& other) +{ +#if __APPLE__ + if (__ptr_ != other.__ptr_) + { + __cxxabiapple::__cxa_increment_exception_refcount(other.__ptr_); + __cxxabiapple::__cxa_decrement_exception_refcount(__ptr_); + __ptr_ = other.__ptr_; + } + return *this; +#else + #warning exception_ptr not yet implemented + ::abort(); +#endif +} + +} // std + + +std::exception_ptr std::current_exception() +{ +#if __APPLE__ + // 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()); + std::exception_ptr ptr; + ptr.__ptr_ = __cxxabiapple::__cxa_current_primary_exception(); + return ptr; +#else + #warning exception_ptr not yet implemented + ::abort(); +#endif +} + +void std::rethrow_exception(exception_ptr p) +{ +#if __APPLE__ + __cxxabiapple::__cxa_rethrow_primary_exception(p.__ptr_); + // if p.__ptr_ is NULL, above returns so we terminate + terminate(); +#else + #warning exception_ptr not yet implemented + ::abort(); +#endif +} + diff --git a/libcxx/src/new.cpp b/libcxx/src/new.cpp index 32e0cbd801f..bc105cc4859 100644 --- a/libcxx/src/new.cpp +++ b/libcxx/src/new.cpp @@ -7,11 +7,136 @@ // //===----------------------------------------------------------------------===// +#include <stdlib.h> +#include <cxxabi.h> + #include "new" + +#if __APPLE__ + // On Darwin, there are two STL shared libraries and a lower level ABI + // shared libray. The global holding the current new handler is + // in the ABI library and named __cxa_new_handler. + #define __new_handler __cxxabiapple::__cxa_new_handler +#else + static std::new_handler __new_handler; +#endif + + +// Implement all new and delete operators as weak definitions +// in this shared library, so that they can be overriden by programs +// that define non-weak copies of the functions. + + +__attribute__((__weak__, __visibility__("default"))) +void * +operator new(std::size_t size) throw (std::bad_alloc) +{ + if (size == 0) + size = 1; + void* p; + while ((p = ::malloc(size)) == 0) + { + // If malloc fails and there is a new_handler, + // call it to try free up memory. + if (__new_handler) + __new_handler(); + else + throw std::bad_alloc(); + } + return p; +} + +__attribute__((__weak__, __visibility__("default"))) +void* +operator new(size_t size, const std::nothrow_t&) throw() +{ + void* p = 0; + try + { + p = ::operator new(size); + } + catch (...) + { + } + return p; +} + +__attribute__((__weak__, __visibility__("default"))) +void* +operator new[](size_t size) throw (std::bad_alloc) +{ + return ::operator new(size); +} + +__attribute__((__weak__, __visibility__("default"))) +void* +operator new[](size_t size, const std::nothrow_t& nothrow) throw() +{ + void* p = 0; + try + { + p = ::operator new[](size); + } + catch (...) + { + } + return p; +} + +__attribute__((__weak__, __visibility__("default"))) +void +operator delete(void* ptr) throw () +{ + if (ptr) + ::free(ptr); +} + +__attribute__((__weak__, __visibility__("default"))) +void +operator delete(void* ptr, const std::nothrow_t&) throw () +{ + ::operator delete(ptr); +} + + +__attribute__((__weak__, __visibility__("default"))) +void +operator delete[] (void* ptr) throw () +{ + ::operator delete (ptr); +} + +__attribute__((__weak__, __visibility__("default"))) +void +operator delete[] (void* ptr, const std::nothrow_t&) throw () +{ + ::operator delete[](ptr); +} + + namespace std { +bad_alloc::bad_alloc() throw() +{ +} + +bad_alloc::~bad_alloc() throw() +{ +} + +const char* +bad_alloc::what() const throw() +{ + return "std::bad_alloc"; +} + + +bad_array_new_length::bad_array_new_length() throw() +{ +} + bad_array_new_length::~bad_array_new_length() throw() { } @@ -22,6 +147,8 @@ bad_array_new_length::what() const throw() return "bad_array_new_length"; } + + void __throw_bad_alloc() { diff --git a/libcxx/src/typeinfo.cpp b/libcxx/src/typeinfo.cpp new file mode 100644 index 00000000000..8606897e5e0 --- /dev/null +++ b/libcxx/src/typeinfo.cpp @@ -0,0 +1,41 @@ +//===------------------------- typeinfo.cpp -------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include <stdlib.h> + +#include "typeinfo" + +std::bad_cast::bad_cast() throw() +{ +} + +std::bad_cast::~bad_cast() throw() +{ +} + +const char* +std::bad_cast::what() const throw() +{ + return "std::bad_cast"; +} + + +std::bad_typeid::bad_typeid() throw() +{ +} + +std::bad_typeid::~bad_typeid() throw() +{ +} + +const char* +std::bad_typeid::what() const throw() +{ + return "std::bad_typeid"; +} + |