diff options
Diffstat (limited to 'libcxx/src/new.cpp')
-rw-r--r-- | libcxx/src/new.cpp | 127 |
1 files changed, 127 insertions, 0 deletions
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() { |