00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <cxxabi.h>
00034 #include <new>
00035 #include <exception>
00036 #include <exception_defines.h>
00037
00038 #include "unwind-cxx.h"
00039
00040 namespace __cxxabiv1
00041 {
00042 namespace
00043 {
00044 struct uncatch_exception
00045 {
00046 uncatch_exception ();
00047 ~uncatch_exception () { __cxa_begin_catch (&p->unwindHeader); }
00048
00049 __cxa_exception *p;
00050 };
00051
00052 uncatch_exception::uncatch_exception ()
00053 {
00054 __cxa_eh_globals *globals = __cxa_get_globals_fast ();
00055
00056 p = globals->caughtExceptions;
00057 p->handlerCount -= 1;
00058 globals->caughtExceptions = p->nextException;
00059 globals->uncaughtExceptions += 1;
00060 }
00061 }
00062
00063
00064 extern "C" void *
00065 __cxa_vec_new(std::size_t element_count,
00066 std::size_t element_size,
00067 std::size_t padding_size,
00068 void (*constructor) (void *),
00069 void (*destructor) (void *))
00070 {
00071 return __cxa_vec_new2(element_count, element_size, padding_size,
00072 constructor, destructor,
00073 &operator new[], &operator delete []);
00074 }
00075
00076 extern "C" void *
00077 __cxa_vec_new2(std::size_t element_count,
00078 std::size_t element_size,
00079 std::size_t padding_size,
00080 void (*constructor) (void *),
00081 void (*destructor) (void *),
00082 void *(*alloc) (std::size_t),
00083 void (*dealloc) (void *))
00084 {
00085 std::size_t size = element_count * element_size + padding_size;
00086 char *base = static_cast <char *> (alloc (size));
00087
00088 if (padding_size)
00089 {
00090 base += padding_size;
00091 reinterpret_cast <std::size_t *> (base)[-1] = element_count;
00092 }
00093 try
00094 {
00095 __cxa_vec_ctor(base, element_count, element_size,
00096 constructor, destructor);
00097 }
00098 catch (...)
00099 {
00100 {
00101 uncatch_exception ue;
00102 dealloc(base - padding_size);
00103 }
00104 __throw_exception_again;
00105 }
00106 return base;
00107 }
00108
00109 extern "C" void *
00110 __cxa_vec_new3(std::size_t element_count,
00111 std::size_t element_size,
00112 std::size_t padding_size,
00113 void (*constructor) (void *),
00114 void (*destructor) (void *),
00115 void *(*alloc) (std::size_t),
00116 void (*dealloc) (void *, std::size_t))
00117 {
00118 std::size_t size = element_count * element_size + padding_size;
00119 char *base = static_cast<char *>(alloc (size));
00120
00121 if (padding_size)
00122 {
00123 base += padding_size;
00124 reinterpret_cast<std::size_t *>(base)[-1] = element_count;
00125 }
00126 try
00127 {
00128 __cxa_vec_ctor(base, element_count, element_size,
00129 constructor, destructor);
00130 }
00131 catch (...)
00132 {
00133 {
00134 uncatch_exception ue;
00135 dealloc(base - padding_size, size);
00136 }
00137 __throw_exception_again;
00138 }
00139 return base;
00140 }
00141
00142
00143 extern "C" void
00144 __cxa_vec_ctor(void *array_address,
00145 std::size_t element_count,
00146 std::size_t element_size,
00147 void (*constructor) (void *),
00148 void (*destructor) (void *))
00149 {
00150 std::size_t ix = 0;
00151 char *ptr = static_cast<char *>(array_address);
00152
00153 try
00154 {
00155 if (constructor)
00156 for (; ix != element_count; ix++, ptr += element_size)
00157 constructor(ptr);
00158 }
00159 catch (...)
00160 {
00161 {
00162 uncatch_exception ue;
00163 __cxa_vec_cleanup(array_address, ix, element_size, destructor);
00164 }
00165 __throw_exception_again;
00166 }
00167 }
00168
00169
00170 extern "C" void
00171 __cxa_vec_cctor(void *dest_array,
00172 void *src_array,
00173 std::size_t element_count,
00174 std::size_t element_size,
00175 void (*constructor) (void *, void *),
00176 void (*destructor) (void *))
00177 {
00178 std::size_t ix = 0;
00179 char *dest_ptr = static_cast<char *>(dest_array);
00180 char *src_ptr = static_cast<char *>(src_array);
00181
00182 try
00183 {
00184 if (constructor)
00185 for (; ix != element_count;
00186 ix++, src_ptr += element_size, dest_ptr += element_size)
00187 constructor(dest_ptr, src_ptr);
00188 }
00189 catch (...)
00190 {
00191 {
00192 uncatch_exception ue;
00193 __cxa_vec_cleanup(dest_array, ix, element_size, destructor);
00194 }
00195 __throw_exception_again;
00196 }
00197 }
00198
00199
00200 extern "C" void
00201 __cxa_vec_dtor(void *array_address,
00202 std::size_t element_count,
00203 std::size_t element_size,
00204 void (*destructor) (void *))
00205 {
00206 if (destructor)
00207 {
00208 char *ptr = static_cast<char *>(array_address);
00209 std::size_t ix = element_count;
00210
00211 ptr += element_count * element_size;
00212
00213 try
00214 {
00215 while (ix--)
00216 {
00217 ptr -= element_size;
00218 destructor(ptr);
00219 }
00220 }
00221 catch (...)
00222 {
00223 {
00224 uncatch_exception ue;
00225 __cxa_vec_cleanup(array_address, ix, element_size, destructor);
00226 }
00227 __throw_exception_again;
00228 }
00229 }
00230 }
00231
00232
00233
00234
00235 extern "C" void
00236 __cxa_vec_cleanup(void *array_address,
00237 std::size_t element_count,
00238 std::size_t element_size,
00239 void (*destructor) (void *))
00240 {
00241 if (destructor)
00242 {
00243 char *ptr = static_cast <char *> (array_address);
00244 std::size_t ix = element_count;
00245
00246 ptr += element_count * element_size;
00247
00248 try
00249 {
00250 while (ix--)
00251 {
00252 ptr -= element_size;
00253 destructor(ptr);
00254 }
00255 }
00256 catch (...)
00257 {
00258 std::terminate();
00259 }
00260 }
00261 }
00262
00263
00264 extern "C" void
00265 __cxa_vec_delete(void *array_address,
00266 std::size_t element_size,
00267 std::size_t padding_size,
00268 void (*destructor) (void *))
00269 {
00270 __cxa_vec_delete2(array_address, element_size, padding_size,
00271 destructor,
00272 &operator delete []);
00273 }
00274
00275 extern "C" void
00276 __cxa_vec_delete2(void *array_address,
00277 std::size_t element_size,
00278 std::size_t padding_size,
00279 void (*destructor) (void *),
00280 void (*dealloc) (void *))
00281 {
00282 char *base = static_cast<char *>(array_address);
00283
00284 if (padding_size)
00285 {
00286 std::size_t element_count = reinterpret_cast<std::size_t *>(base)[-1];
00287 base -= padding_size;
00288 try
00289 {
00290 __cxa_vec_dtor(array_address, element_count, element_size,
00291 destructor);
00292 }
00293 catch (...)
00294 {
00295 {
00296 uncatch_exception ue;
00297 dealloc(base);
00298 }
00299 __throw_exception_again;
00300 }
00301 }
00302 dealloc(base);
00303 }
00304
00305 extern "C" void
00306 __cxa_vec_delete3(void *array_address,
00307 std::size_t element_size,
00308 std::size_t padding_size,
00309 void (*destructor) (void *),
00310 void (*dealloc) (void *, std::size_t))
00311 {
00312 char *base = static_cast <char *> (array_address);
00313 std::size_t size = 0;
00314
00315 if (padding_size)
00316 {
00317 std::size_t element_count = reinterpret_cast<std::size_t *> (base)[-1];
00318 base -= padding_size;
00319 size = element_count * element_size + padding_size;
00320 try
00321 {
00322 __cxa_vec_dtor(array_address, element_count, element_size,
00323 destructor);
00324 }
00325 catch (...)
00326 {
00327 {
00328 uncatch_exception ue;
00329 dealloc(base, size);
00330 }
00331 __throw_exception_again;
00332 }
00333 }
00334 dealloc(base, size);
00335 }
00336 }
00337