1 // -*- C++ -*- 2 //===----------------------------------------------------------------------===// 3 // 4 // The LLVM Compiler Infrastructure 5 // 6 // This file is dual licensed under the MIT and the University of Illinois Open 7 // Source Licenses. See LICENSE.TXT for details. 8 // 9 //===----------------------------------------------------------------------===// 10 11 #include <cstdio> 12 13 namespace std { 14 15 _LIBCPP_SAFE_STATIC static std::terminate_handler __terminate_handler; 16 _LIBCPP_SAFE_STATIC static std::unexpected_handler __unexpected_handler; 17 18 19 // libcxxrt provides implementations of these functions itself. 20 unexpected_handler 21 set_unexpected(unexpected_handler func) _NOEXCEPT 22 { 23 return __sync_lock_test_and_set(&__unexpected_handler, func); 24 } 25 26 unexpected_handler 27 get_unexpected() _NOEXCEPT 28 { 29 return __sync_fetch_and_add(&__unexpected_handler, (unexpected_handler)0); 30 31 } 32 33 _LIBCPP_NORETURN 34 void unexpected() 35 { 36 (*get_unexpected())(); 37 // unexpected handler should not return 38 terminate(); 39 } 40 41 terminate_handler 42 set_terminate(terminate_handler func) _NOEXCEPT 43 { 44 return __sync_lock_test_and_set(&__terminate_handler, func); 45 } 46 47 terminate_handler 48 get_terminate() _NOEXCEPT 49 { 50 return __sync_fetch_and_add(&__terminate_handler, (terminate_handler)0); 51 52 } 53 54 #ifndef __EMSCRIPTEN__ // We provide this in JS 55 _LIBCPP_NORETURN 56 void 57 terminate() _NOEXCEPT 58 { 59 #ifndef _LIBCPP_NO_EXCEPTIONS 60 try 61 { 62 #endif // _LIBCPP_NO_EXCEPTIONS 63 (*get_terminate())(); 64 // handler should not return 65 fprintf(stderr, "terminate_handler unexpectedly returned\n"); 66 ::abort(); 67 #ifndef _LIBCPP_NO_EXCEPTIONS 68 } 69 catch (...) 70 { 71 // handler should not throw exception 72 fprintf(stderr, "terminate_handler unexpectedly threw an exception\n"); 73 ::abort(); 74 } 75 #endif // _LIBCPP_NO_EXCEPTIONS 76 } 77 #endif // !__EMSCRIPTEN__ 78 79 #if !defined(__EMSCRIPTEN__) 80 bool uncaught_exception() _NOEXCEPT { return uncaught_exceptions() > 0; } 81 82 int uncaught_exceptions() _NOEXCEPT 83 { 84 #warning uncaught_exception not yet implemented 85 fprintf(stderr, "uncaught_exceptions not yet implemented\n"); 86 ::abort(); 87 } 88 #endif // !__EMSCRIPTEN__ 89 90 91 exception::~exception() _NOEXCEPT 92 { 93 } 94 95 const char* exception::what() const _NOEXCEPT 96 { 97 return "std::exception"; 98 } 99 100 bad_exception::~bad_exception() _NOEXCEPT 101 { 102 } 103 104 const char* bad_exception::what() const _NOEXCEPT 105 { 106 return "std::bad_exception"; 107 } 108 109 110 bad_alloc::bad_alloc() _NOEXCEPT 111 { 112 } 113 114 bad_alloc::~bad_alloc() _NOEXCEPT 115 { 116 } 117 118 const char* 119 bad_alloc::what() const _NOEXCEPT 120 { 121 return "std::bad_alloc"; 122 } 123 124 bad_array_new_length::bad_array_new_length() _NOEXCEPT 125 { 126 } 127 128 bad_array_new_length::~bad_array_new_length() _NOEXCEPT 129 { 130 } 131 132 const char* 133 bad_array_new_length::what() const _NOEXCEPT 134 { 135 return "bad_array_new_length"; 136 } 137 138 139 bad_array_length::bad_array_length() _NOEXCEPT 140 { 141 } 142 143 bad_array_length::~bad_array_length() _NOEXCEPT 144 { 145 } 146 147 const char* 148 bad_array_length::what() const _NOEXCEPT 149 { 150 return "bad_array_length"; 151 } 152 153 154 bad_cast::bad_cast() _NOEXCEPT 155 { 156 } 157 158 bad_typeid::bad_typeid() _NOEXCEPT 159 { 160 } 161 162 bad_cast::~bad_cast() _NOEXCEPT 163 { 164 } 165 166 const char* 167 bad_cast::what() const _NOEXCEPT 168 { 169 return "std::bad_cast"; 170 } 171 172 bad_typeid::~bad_typeid() _NOEXCEPT 173 { 174 } 175 176 const char* 177 bad_typeid::what() const _NOEXCEPT 178 { 179 return "std::bad_typeid"; 180 } 181 182 } // namespace std 183