diff options
Diffstat (limited to 'contrib/libc++/src/new.cpp')
-rw-r--r-- | contrib/libc++/src/new.cpp | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/contrib/libc++/src/new.cpp b/contrib/libc++/src/new.cpp new file mode 100644 index 0000000..a88d4cc --- /dev/null +++ b/contrib/libc++/src/new.cpp @@ -0,0 +1,239 @@ +//===--------------------------- new.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. +// +//===----------------------------------------------------------------------===// + +#define _LIBCPP_BUILDING_NEW + +#include <stdlib.h> + +#include "new" + +#ifndef __has_include +#define __has_include(inc) 0 +#endif + +#if defined(__APPLE__) && !defined(LIBCXXRT) + #include <cxxabi.h> + + #ifndef _LIBCPPABI_VERSION + // On Darwin, there are two STL shared libraries and a lower level ABI + // shared library. The global holding the current new handler is + // in the ABI library and named __cxa_new_handler. + #define __new_handler __cxxabiapple::__cxa_new_handler + #endif +#else // __APPLE__ + #if defined(LIBCXXRT) || __has_include(<cxxabi.h>) + #include <cxxabi.h> + #endif // __has_include(<cxxabi.h>) + #if !defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__) + static std::new_handler __new_handler; + #endif // _LIBCPPABI_VERSION +#endif + +#ifndef __GLIBCXX__ + +// 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. + +_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS +void * +operator new(std::size_t size) +#if !__has_feature(cxx_noexcept) + throw(std::bad_alloc) +#endif +{ + 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. + std::new_handler nh = std::get_new_handler(); + if (nh) + nh(); + else +#ifndef _LIBCPP_NO_EXCEPTIONS + throw std::bad_alloc(); +#else + break; +#endif + } + return p; +} + +_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS +void* +operator new(size_t size, const std::nothrow_t&) _NOEXCEPT +{ + void* p = 0; +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + p = ::operator new(size); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + } +#endif // _LIBCPP_NO_EXCEPTIONS + return p; +} + +_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS +void* +operator new[](size_t size) +#if !__has_feature(cxx_noexcept) + throw(std::bad_alloc) +#endif +{ + return ::operator new(size); +} + +_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS +void* +operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT +{ + void* p = 0; +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + p = ::operator new[](size); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + } +#endif // _LIBCPP_NO_EXCEPTIONS + return p; +} + +_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS +void +operator delete(void* ptr) _NOEXCEPT +{ + if (ptr) + ::free(ptr); +} + +_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS +void +operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT +{ + ::operator delete(ptr); +} + +_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS +void +operator delete[] (void* ptr) _NOEXCEPT +{ + ::operator delete (ptr); +} + +_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS +void +operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT +{ + ::operator delete[](ptr); +} + +#endif // !__GLIBCXX__ + +namespace std +{ + +#ifndef __GLIBCXX__ +const nothrow_t nothrow = {}; +#endif + +#ifndef _LIBCPPABI_VERSION + +#ifndef __GLIBCXX__ + +new_handler +set_new_handler(new_handler handler) _NOEXCEPT +{ + return __sync_lock_test_and_set(&__new_handler, handler); +} + +new_handler +get_new_handler() _NOEXCEPT +{ + return __sync_fetch_and_add(&__new_handler, nullptr); +} + +#endif // !__GLIBCXX__ + +#ifndef LIBCXXRT + +bad_alloc::bad_alloc() _NOEXCEPT +{ +} + +#ifndef __GLIBCXX__ + +bad_alloc::~bad_alloc() _NOEXCEPT +{ +} + +const char* +bad_alloc::what() const _NOEXCEPT +{ + return "std::bad_alloc"; +} + +#endif // !__GLIBCXX__ + +bad_array_new_length::bad_array_new_length() _NOEXCEPT +{ +} + +bad_array_new_length::~bad_array_new_length() _NOEXCEPT +{ +} + +const char* +bad_array_new_length::what() const _NOEXCEPT +{ + return "bad_array_new_length"; +} + +#endif //LIBCXXRT + +const char* +bad_array_length::what() const _NOEXCEPT +{ + return "bad_array_length"; +} + +bad_array_length::bad_array_length() _NOEXCEPT +{ +} + +bad_array_length::~bad_array_length() _NOEXCEPT +{ +} + +#endif // _LIBCPPABI_VERSION + +#ifndef LIBSTDCXX + +void +__throw_bad_alloc() +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_alloc(); +#endif +} + +#endif // !LIBSTDCXX + +} // std |