stdexcept.cpp revision 232950
1227825Stheraven//===------------------------ stdexcept.cpp -------------------------------===// 2227825Stheraven// 3227825Stheraven// The LLVM Compiler Infrastructure 4227825Stheraven// 5227825Stheraven// This file is dual licensed under the MIT and the University of Illinois Open 6227825Stheraven// Source Licenses. See LICENSE.TXT for details. 7227825Stheraven// 8227825Stheraven//===----------------------------------------------------------------------===// 9227825Stheraven 10227825Stheraven#include "stdexcept" 11227825Stheraven#include "new" 12227825Stheraven#include "string" 13227825Stheraven#include <cstdlib> 14227825Stheraven#include <cstring> 15227825Stheraven#include <cstdint> 16227825Stheraven#include <cstddef> 17227825Stheraven#include "system_error" 18232950Stheraven#include <cxxabi.h> 19227825Stheraven 20227825Stheraven// Note: optimize for size 21227825Stheraven 22227825Stheraven#pragma GCC visibility push(hidden) 23227825Stheraven 24227825Stheravennamespace 25227825Stheraven{ 26227825Stheraven 27227825Stheravenclass __libcpp_nmstr 28227825Stheraven{ 29227825Stheravenprivate: 30227825Stheraven const char* str_; 31227825Stheraven 32227825Stheraven typedef std::size_t unused_t; 33227825Stheraven typedef std::int32_t count_t; 34227825Stheraven 35227825Stheraven static const std::ptrdiff_t offset = static_cast<std::ptrdiff_t>(2*sizeof(unused_t) + 36227825Stheraven sizeof(count_t)); 37227825Stheraven 38227825Stheraven count_t& count() const _NOEXCEPT {return (count_t&)(*(str_ - sizeof(count_t)));} 39227825Stheravenpublic: 40227825Stheraven explicit __libcpp_nmstr(const char* msg); 41227825Stheraven __libcpp_nmstr(const __libcpp_nmstr& s) _LIBCPP_CANTTHROW; 42227825Stheraven __libcpp_nmstr& operator=(const __libcpp_nmstr& s) _LIBCPP_CANTTHROW; 43227825Stheraven ~__libcpp_nmstr() _LIBCPP_CANTTHROW; 44227825Stheraven const char* c_str() const _NOEXCEPT {return str_;} 45227825Stheraven}; 46227825Stheraven 47227825Stheraven__libcpp_nmstr::__libcpp_nmstr(const char* msg) 48227825Stheraven{ 49227825Stheraven std::size_t len = strlen(msg); 50227825Stheraven str_ = new char[len + 1 + offset]; 51227825Stheraven unused_t* c = (unused_t*)str_; 52227825Stheraven c[0] = c[1] = len; 53227825Stheraven str_ += offset; 54227825Stheraven count() = 0; 55227825Stheraven std::strcpy(const_cast<char*>(c_str()), msg); 56227825Stheraven} 57227825Stheraven 58227825Stheraveninline 59227825Stheraven__libcpp_nmstr::__libcpp_nmstr(const __libcpp_nmstr& s) 60227825Stheraven : str_(s.str_) 61227825Stheraven{ 62227825Stheraven __sync_add_and_fetch(&count(), 1); 63227825Stheraven} 64227825Stheraven 65227825Stheraven__libcpp_nmstr& 66227825Stheraven__libcpp_nmstr::operator=(const __libcpp_nmstr& s) 67227825Stheraven{ 68227825Stheraven const char* p = str_; 69227825Stheraven str_ = s.str_; 70227825Stheraven __sync_add_and_fetch(&count(), 1); 71227825Stheraven if (__sync_add_and_fetch((count_t*)(p-sizeof(count_t)), -1) < 0) 72227825Stheraven delete [] (p-offset); 73227825Stheraven return *this; 74227825Stheraven} 75227825Stheraven 76227825Stheraveninline 77227825Stheraven__libcpp_nmstr::~__libcpp_nmstr() 78227825Stheraven{ 79227825Stheraven if (__sync_add_and_fetch(&count(), -1) < 0) 80227825Stheraven delete [] (str_ - offset); 81227825Stheraven} 82227825Stheraven 83227825Stheraven} 84227825Stheraven 85227825Stheraven#pragma GCC visibility pop 86227825Stheraven 87227825Stheravennamespace std // purposefully not using versioning namespace 88227825Stheraven{ 89227825Stheraven 90227825Stheravenlogic_error::logic_error(const string& msg) 91227825Stheraven{ 92227825Stheraven __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 93227825Stheraven ::new(&s) __libcpp_nmstr(msg.c_str()); 94227825Stheraven} 95227825Stheraven 96227825Stheravenlogic_error::logic_error(const char* msg) 97227825Stheraven{ 98227825Stheraven __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 99227825Stheraven ::new(&s) __libcpp_nmstr(msg); 100227825Stheraven} 101227825Stheraven 102227825Stheravenlogic_error::logic_error(const logic_error& le) _NOEXCEPT 103227825Stheraven{ 104227825Stheraven __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 105227825Stheraven ::new(&s) __libcpp_nmstr((const __libcpp_nmstr&)le.__imp_); 106227825Stheraven} 107227825Stheraven 108227825Stheravenlogic_error& 109227825Stheravenlogic_error::operator=(const logic_error& le) _NOEXCEPT 110227825Stheraven{ 111227825Stheraven __libcpp_nmstr& s1 = (__libcpp_nmstr&)__imp_; 112227825Stheraven const __libcpp_nmstr& s2 = (const __libcpp_nmstr&)le.__imp_; 113227825Stheraven s1 = s2; 114227825Stheraven return *this; 115227825Stheraven} 116227825Stheraven 117232950Stheraven#ifndef _LIBCPPABI_VERSION 118232950Stheraven 119227825Stheravenlogic_error::~logic_error() _NOEXCEPT 120227825Stheraven{ 121227825Stheraven __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 122227825Stheraven s.~__libcpp_nmstr(); 123227825Stheraven} 124227825Stheraven 125227825Stheravenconst char* 126227825Stheravenlogic_error::what() const _NOEXCEPT 127227825Stheraven{ 128227825Stheraven __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 129227825Stheraven return s.c_str(); 130227825Stheraven} 131227825Stheraven 132232950Stheraven#endif 133232950Stheraven 134227825Stheravenruntime_error::runtime_error(const string& msg) 135227825Stheraven{ 136227825Stheraven __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 137227825Stheraven ::new(&s) __libcpp_nmstr(msg.c_str()); 138227825Stheraven} 139227825Stheraven 140227825Stheravenruntime_error::runtime_error(const char* msg) 141227825Stheraven{ 142227825Stheraven __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 143227825Stheraven ::new(&s) __libcpp_nmstr(msg); 144227825Stheraven} 145227825Stheraven 146227825Stheravenruntime_error::runtime_error(const runtime_error& le) _NOEXCEPT 147227825Stheraven{ 148227825Stheraven __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 149227825Stheraven ::new(&s) __libcpp_nmstr((const __libcpp_nmstr&)le.__imp_); 150227825Stheraven} 151227825Stheraven 152227825Stheravenruntime_error& 153227825Stheravenruntime_error::operator=(const runtime_error& le) _NOEXCEPT 154227825Stheraven{ 155227825Stheraven __libcpp_nmstr& s1 = (__libcpp_nmstr&)__imp_; 156227825Stheraven const __libcpp_nmstr& s2 = (const __libcpp_nmstr&)le.__imp_; 157227825Stheraven s1 = s2; 158227825Stheraven return *this; 159227825Stheraven} 160227825Stheraven 161232950Stheraven#ifndef _LIBCPPABI_VERSION 162232950Stheraven 163227825Stheravenruntime_error::~runtime_error() _NOEXCEPT 164227825Stheraven{ 165227825Stheraven __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 166227825Stheraven s.~__libcpp_nmstr(); 167227825Stheraven} 168227825Stheraven 169227825Stheravenconst char* 170227825Stheravenruntime_error::what() const _NOEXCEPT 171227825Stheraven{ 172227825Stheraven __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 173227825Stheraven return s.c_str(); 174227825Stheraven} 175227825Stheraven 176227825Stheravendomain_error::~domain_error() _NOEXCEPT {} 177227825Stheraveninvalid_argument::~invalid_argument() _NOEXCEPT {} 178227825Stheravenlength_error::~length_error() _NOEXCEPT {} 179227825Stheravenout_of_range::~out_of_range() _NOEXCEPT {} 180227825Stheraven 181227825Stheravenrange_error::~range_error() _NOEXCEPT {} 182227825Stheravenoverflow_error::~overflow_error() _NOEXCEPT {} 183227825Stheravenunderflow_error::~underflow_error() _NOEXCEPT {} 184227825Stheraven 185232950Stheraven#endif 186232950Stheraven 187227825Stheraven} // std 188