vec.cc revision 97403
1// New abi Support -*- C++ -*- 2 3// Copyright (C) 2000, 2001 Free Software Foundation, Inc. 4// 5// This file is part of GNU CC. 6// 7// GNU CC is free software; you can redistribute it and/or modify 8// it under the terms of the GNU General Public License as published by 9// the Free Software Foundation; either version 2, or (at your option) 10// any later version. 11 12// GNU CC is distributed in the hope that it will be useful, 13// but WITHOUT ANY WARRANTY; without even the implied warranty of 14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15// GNU General Public License for more details. 16 17// You should have received a copy of the GNU General Public License 18// along with GNU CC; see the file COPYING. If not, write to 19// the Free Software Foundation, 59 Temple Place - Suite 330, 20// Boston, MA 02111-1307, USA. 21 22// As a special exception, you may use this file as part of a free software 23// library without restriction. Specifically, if other files instantiate 24// templates or use macros or inline functions from this file, or you compile 25// this file and link it with other files to produce an executable, this 26// file does not by itself cause the resulting executable to be covered by 27// the GNU General Public License. This exception does not however 28// invalidate any other reasons why the executable file might be covered by 29// the GNU General Public License. 30 31// Written by Nathan Sidwell, Codesourcery LLC, <nathan@codesourcery.com> 32 33#include <cxxabi.h> 34#include <new> 35#include <exception> 36#include <exception_defines.h> 37#include "unwind-cxx.h" 38 39namespace __cxxabiv1 40{ 41 namespace 42 { 43 struct uncatch_exception 44 { 45 uncatch_exception (); 46 ~uncatch_exception () { __cxa_begin_catch (&p->unwindHeader); } 47 48 __cxa_exception *p; 49 }; 50 51 uncatch_exception::uncatch_exception () 52 { 53 __cxa_eh_globals *globals = __cxa_get_globals_fast (); 54 55 p = globals->caughtExceptions; 56 p->handlerCount -= 1; 57 globals->caughtExceptions = p->nextException; 58 globals->uncaughtExceptions += 1; 59 } 60 } 61 62 // Allocate and construct array. 63 extern "C" void * 64 __cxa_vec_new(std::size_t element_count, 65 std::size_t element_size, 66 std::size_t padding_size, 67 void (*constructor) (void *), 68 void (*destructor) (void *)) 69 { 70 return __cxa_vec_new2(element_count, element_size, padding_size, 71 constructor, destructor, 72 &operator new[], &operator delete []); 73 } 74 75 extern "C" void * 76 __cxa_vec_new2(std::size_t element_count, 77 std::size_t element_size, 78 std::size_t padding_size, 79 void (*constructor) (void *), 80 void (*destructor) (void *), 81 void *(*alloc) (std::size_t), 82 void (*dealloc) (void *)) 83 { 84 std::size_t size = element_count * element_size + padding_size; 85 char *base = static_cast <char *> (alloc (size)); 86 87 if (padding_size) 88 { 89 base += padding_size; 90 reinterpret_cast <std::size_t *> (base)[-1] = element_count; 91 } 92 try 93 { 94 __cxa_vec_ctor(base, element_count, element_size, 95 constructor, destructor); 96 } 97 catch (...) 98 { 99 { 100 uncatch_exception ue; 101 dealloc(base - padding_size); 102 } 103 __throw_exception_again; 104 } 105 return base; 106 } 107 108 extern "C" void * 109 __cxa_vec_new3(std::size_t element_count, 110 std::size_t element_size, 111 std::size_t padding_size, 112 void (*constructor) (void *), 113 void (*destructor) (void *), 114 void *(*alloc) (std::size_t), 115 void (*dealloc) (void *, std::size_t)) 116 { 117 std::size_t size = element_count * element_size + padding_size; 118 char *base = static_cast<char *>(alloc (size)); 119 120 if (padding_size) 121 { 122 base += padding_size; 123 reinterpret_cast<std::size_t *>(base)[-1] = element_count; 124 } 125 try 126 { 127 __cxa_vec_ctor(base, element_count, element_size, 128 constructor, destructor); 129 } 130 catch (...) 131 { 132 { 133 uncatch_exception ue; 134 dealloc(base - padding_size, size); 135 } 136 __throw_exception_again; 137 } 138 return base; 139 } 140 141 // Construct array. 142 extern "C" void 143 __cxa_vec_ctor(void *array_address, 144 std::size_t element_count, 145 std::size_t element_size, 146 void (*constructor) (void *), 147 void (*destructor) (void *)) 148 { 149 std::size_t ix = 0; 150 char *ptr = static_cast<char *>(array_address); 151 152 try 153 { 154 if (constructor) 155 for (; ix != element_count; ix++, ptr += element_size) 156 constructor(ptr); 157 } 158 catch (...) 159 { 160 { 161 uncatch_exception ue; 162 __cxa_vec_cleanup(array_address, ix, element_size, destructor); 163 } 164 __throw_exception_again; 165 } 166 } 167 168 // Construct an array by copying. 169 extern "C" void 170 __cxa_vec_cctor(void *dest_array, 171 void *src_array, 172 std::size_t element_count, 173 std::size_t element_size, 174 void (*constructor) (void *, void *), 175 void (*destructor) (void *)) 176 { 177 std::size_t ix = 0; 178 char *dest_ptr = static_cast<char *>(dest_array); 179 char *src_ptr = static_cast<char *>(src_array); 180 181 try 182 { 183 if (constructor) 184 for (; ix != element_count; 185 ix++, src_ptr += element_size, dest_ptr += element_size) 186 constructor(dest_ptr, src_ptr); 187 } 188 catch (...) 189 { 190 { 191 uncatch_exception ue; 192 __cxa_vec_cleanup(dest_array, ix, element_size, destructor); 193 } 194 __throw_exception_again; 195 } 196 } 197 198 // Destruct array. 199 extern "C" void 200 __cxa_vec_dtor(void *array_address, 201 std::size_t element_count, 202 std::size_t element_size, 203 void (*destructor) (void *)) 204 { 205 if (destructor) 206 { 207 char *ptr = static_cast<char *>(array_address); 208 std::size_t ix = element_count; 209 210 ptr += element_count * element_size; 211 212 try 213 { 214 while (ix--) 215 { 216 ptr -= element_size; 217 destructor(ptr); 218 } 219 } 220 catch (...) 221 { 222 { 223 uncatch_exception ue; 224 __cxa_vec_cleanup(array_address, ix, element_size, destructor); 225 } 226 __throw_exception_again; 227 } 228 } 229 } 230 231 // Destruct array as a result of throwing an exception. 232 // [except.ctor]/3 If a destructor called during stack unwinding 233 // exits with an exception, terminate is called. 234 extern "C" void 235 __cxa_vec_cleanup(void *array_address, 236 std::size_t element_count, 237 std::size_t element_size, 238 void (*destructor) (void *)) 239 { 240 if (destructor) 241 { 242 char *ptr = static_cast <char *> (array_address); 243 std::size_t ix = element_count; 244 245 ptr += element_count * element_size; 246 247 try 248 { 249 while (ix--) 250 { 251 ptr -= element_size; 252 destructor(ptr); 253 } 254 } 255 catch (...) 256 { 257 std::terminate(); 258 } 259 } 260 } 261 262 // Destruct and release array. 263 extern "C" void 264 __cxa_vec_delete(void *array_address, 265 std::size_t element_size, 266 std::size_t padding_size, 267 void (*destructor) (void *)) 268 { 269 __cxa_vec_delete2(array_address, element_size, padding_size, 270 destructor, 271 &operator delete []); 272 } 273 274 extern "C" void 275 __cxa_vec_delete2(void *array_address, 276 std::size_t element_size, 277 std::size_t padding_size, 278 void (*destructor) (void *), 279 void (*dealloc) (void *)) 280 { 281 char *base = static_cast<char *>(array_address); 282 283 if (padding_size) 284 { 285 std::size_t element_count = reinterpret_cast<std::size_t *>(base)[-1]; 286 base -= padding_size; 287 try 288 { 289 __cxa_vec_dtor(array_address, element_count, element_size, 290 destructor); 291 } 292 catch (...) 293 { 294 { 295 uncatch_exception ue; 296 dealloc(base); 297 } 298 __throw_exception_again; 299 } 300 } 301 dealloc(base); 302 } 303 304 extern "C" void 305 __cxa_vec_delete3(void *array_address, 306 std::size_t element_size, 307 std::size_t padding_size, 308 void (*destructor) (void *), 309 void (*dealloc) (void *, std::size_t)) 310 { 311 char *base = static_cast <char *> (array_address); 312 std::size_t size = 0; 313 314 if (padding_size) 315 { 316 std::size_t element_count = reinterpret_cast<std::size_t *> (base)[-1]; 317 base -= padding_size; 318 size = element_count * element_size + padding_size; 319 try 320 { 321 __cxa_vec_dtor(array_address, element_count, element_size, 322 destructor); 323 } 324 catch (...) 325 { 326 { 327 uncatch_exception ue; 328 dealloc(base, size); 329 } 330 __throw_exception_again; 331 } 332 } 333 dealloc(base, size); 334 } 335} // namespace __cxxabiv1 336 337