diff options
Diffstat (limited to 'libstdc++-v3/libsupc++/vec.cc')
-rw-r--r-- | libstdc++-v3/libsupc++/vec.cc | 515 |
1 files changed, 275 insertions, 240 deletions
diff --git a/libstdc++-v3/libsupc++/vec.cc b/libstdc++-v3/libsupc++/vec.cc index f00d3c11b23..5bd8ec8a47b 100644 --- a/libstdc++-v3/libsupc++/vec.cc +++ b/libstdc++-v3/libsupc++/vec.cc @@ -1,8 +1,9 @@ -// new abi support -*- C++ -*- -// Copyright (C) 2000 -// Free Software Foundation, Inc. -// Written by Nathan Sidwell, Codesourcery LLC, <nathan@codesourcery.com> -// +// New abi Support -*- C++ -*- + +// Copyright (C) 2000, 2001 Free Software Foundation, Inc. +// +// This file is part of GNU CC. +// // GNU CC is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2, or (at your option) @@ -27,276 +28,310 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 +// Written by Nathan Sidwell, Codesourcery LLC, <nathan@codesourcery.com> + #include <cxxabi.h> #include <new> #include <exception> +#include <exception_defines.h> -#include "exception_support.h" +#include "unwind-cxx.h" namespace __cxxabiv1 { + namespace + { + struct uncatch_exception + { + uncatch_exception (); + ~uncatch_exception () { __cxa_begin_catch (&p->unwindHeader); } + + __cxa_exception *p; + }; -namespace -{ -struct uncatch_exception { - uncatch_exception () { p = __uncatch_exception (); } - ~uncatch_exception () { __recatch_exception (p); } + uncatch_exception::uncatch_exception () + { + __cxa_eh_globals *globals = __cxa_get_globals_fast (); - cp_eh_info *p; -}; -} + p = globals->caughtExceptions; + p->handlerCount -= 1; + globals->caughtExceptions = p->nextException; + globals->uncaughtExceptions += 1; + } + } -/* allocate and construct array */ -extern "C" void * -__cxa_vec_new (std::size_t element_count, - std::size_t element_size, - std::size_t padding_size, - void (*constructor) (void *), - void (*destructor) (void *)) -{ - return __cxa_vec_new2 (element_count, element_size, padding_size, - constructor, destructor, - &operator new[], &operator delete []); -} + // Allocate and construct array. + extern "C" void * + __cxa_vec_new(std::size_t element_count, + std::size_t element_size, + std::size_t padding_size, + void (*constructor) (void *), + void (*destructor) (void *)) + { + return __cxa_vec_new2(element_count, element_size, padding_size, + constructor, destructor, + &operator new[], &operator delete []); + } -extern "C" void * -__cxa_vec_new2 (std::size_t element_count, - std::size_t element_size, - std::size_t padding_size, - void (*constructor) (void *), - void (*destructor) (void *), - void *(*alloc) (size_t), - void (*dealloc) (void *)) -{ - std::size_t size = element_count * element_size + padding_size; - char *base = static_cast <char *> (alloc (size)); + extern "C" void * + __cxa_vec_new2(std::size_t element_count, + std::size_t element_size, + std::size_t padding_size, + void (*constructor) (void *), + void (*destructor) (void *), + void *(*alloc) (std::size_t), + void (*dealloc) (void *)) + { + std::size_t size = element_count * element_size + padding_size; + char *base = static_cast <char *> (alloc (size)); + + if (padding_size) + { + base += padding_size; + reinterpret_cast <std::size_t *> (base)[-1] = element_count; + } + try + { + __cxa_vec_ctor(base, element_count, element_size, + constructor, destructor); + } + catch (...) + { + { + uncatch_exception ue; + dealloc(base - padding_size); + } + __throw_exception_again; + } + return base; + } - if (padding_size) - { - base += padding_size; - reinterpret_cast <std::size_t *> (base)[-1] = element_count; - } - try - { - __cxa_vec_ctor (base, element_count, element_size, - constructor, destructor); - } - catch (...) - { + extern "C" void * + __cxa_vec_new3(std::size_t element_count, + std::size_t element_size, + std::size_t padding_size, + void (*constructor) (void *), + void (*destructor) (void *), + void *(*alloc) (std::size_t), + void (*dealloc) (void *, std::size_t)) + { + std::size_t size = element_count * element_size + padding_size; + char *base = static_cast<char *>(alloc (size)); + + if (padding_size) { - uncatch_exception ue; - dealloc (base - padding_size); + base += padding_size; + reinterpret_cast<std::size_t *>(base)[-1] = element_count; } - throw; - } - return base; -} - -extern "C" void * -__cxa_vec_new3 (std::size_t element_count, - std::size_t element_size, - std::size_t padding_size, - void (*constructor) (void *), - void (*destructor) (void *), - void *(*alloc) (std::size_t), - void (*dealloc) (void *, std::size_t)) -{ - std::size_t size = element_count * element_size + padding_size; - char *base = static_cast <char *> (alloc (size)); + try + { + __cxa_vec_ctor(base, element_count, element_size, + constructor, destructor); + } + catch (...) + { + { + uncatch_exception ue; + dealloc(base - padding_size, size); + } + __throw_exception_again; + } + return base; + } - if (padding_size) - { - base += padding_size; - reinterpret_cast <std::size_t *> (base)[-1] = element_count; - } - try - { - __cxa_vec_ctor (base, element_count, element_size, - constructor, destructor); - } - catch (...) - { + // Construct array. + extern "C" void + __cxa_vec_ctor(void *array_address, + std::size_t element_count, + std::size_t element_size, + void (*constructor) (void *), + void (*destructor) (void *)) + { + std::size_t ix = 0; + char *ptr = static_cast<char *>(array_address); + + try { - uncatch_exception ue; - dealloc (base - padding_size, size); + if (constructor) + for (; ix != element_count; ix++, ptr += element_size) + constructor(ptr); } - throw; - } - return base; -} - -/* construct array */ -extern "C" void -__cxa_vec_ctor (void *array_address, - std::size_t element_count, - std::size_t element_size, - void (*constructor) (void *), - void (*destructor) (void *)) -{ - std::size_t ix = 0; - char *ptr = static_cast <char *> (array_address); + catch (...) + { + { + uncatch_exception ue; + __cxa_vec_cleanup(array_address, ix, element_size, destructor); + } + __throw_exception_again; + } + } - try - { - if (constructor) - for (; ix != element_count; ix++, ptr += element_size) - constructor (ptr); - } - catch (...) - { + // Construct an array by copying. + extern "C" void + __cxa_vec_cctor(void *dest_array, + void *src_array, + std::size_t element_count, + std::size_t element_size, + void (*constructor) (void *, void *), + void (*destructor) (void *)) + { + std::size_t ix = 0; + char *dest_ptr = static_cast<char *>(dest_array); + char *src_ptr = static_cast<char *>(src_array); + + try { - uncatch_exception ue; - __cxa_vec_dtor (array_address, ix, element_size, destructor); + if (constructor) + for (; ix != element_count; + ix++, src_ptr += element_size, dest_ptr += element_size) + constructor(dest_ptr, src_ptr); } - throw; - } -} - -/* construct an array by copying */ - -extern "C" void -__cxa_vec_cctor (void *dest_array, - void *src_array, + catch (...) + { + { + uncatch_exception ue; + __cxa_vec_cleanup(dest_array, ix, element_size, destructor); + } + __throw_exception_again; + } + } + + // Destruct array. + extern "C" void + __cxa_vec_dtor(void *array_address, std::size_t element_count, std::size_t element_size, - void (*constructor) (void *, void *), void (*destructor) (void *)) -{ - std::size_t ix = 0; - char *dest_ptr = static_cast <char *> (dest_array); - char *src_ptr = static_cast <char *> (src_array); - - try - { - if (constructor) - for (; ix != element_count; - ix++, src_ptr += element_size, dest_ptr += element_size) - constructor (dest_ptr, src_ptr); - } - catch (...) - { + { + if (destructor) { - uncatch_exception ue; - __cxa_vec_dtor (dest_array, ix, element_size, destructor); - } - throw; - } -} + char *ptr = static_cast<char *>(array_address); + std::size_t ix = element_count; -/* destruct array */ -extern "C" void -__cxa_vec_dtor (void *array_address, - std::size_t element_count, - std::size_t element_size, - void (*destructor) (void *)) -{ - if (destructor) - { - char *ptr = static_cast <char *> (array_address); - std::size_t ix = element_count; - bool unwinding = std::uncaught_exception (); - - ptr += element_count * element_size; - - try - { - while (ix--) - { - ptr -= element_size; - destructor (ptr); - } - } - catch (...) - { - if (unwinding) - // [except.ctor]/3 If a destructor called during stack unwinding - // exits with an exception, terminate is called. - std::terminate (); + ptr += element_count * element_size; + + try { - uncatch_exception ue; - __cxa_vec_dtor (array_address, ix, element_size, - destructor); + while (ix--) + { + ptr -= element_size; + destructor(ptr); + } } - throw; - } - } -} + catch (...) + { + { + uncatch_exception ue; + __cxa_vec_cleanup(array_address, ix, element_size, destructor); + } + __throw_exception_again; + } + } + } -/* destruct and release array */ -extern "C" void -__cxa_vec_delete (void *array_address, - std::size_t element_size, - std::size_t padding_size, - void (*destructor) (void *)) -{ - __cxa_vec_delete2 (array_address, element_size, padding_size, - destructor, - &operator delete []); -} + // Destruct array as a result of throwing an exception. + // [except.ctor]/3 If a destructor called during stack unwinding + // exits with an exception, terminate is called. + extern "C" void + __cxa_vec_cleanup(void *array_address, + std::size_t element_count, + std::size_t element_size, + void (*destructor) (void *)) + { + if (destructor) + { + char *ptr = static_cast <char *> (array_address); + std::size_t ix = element_count; -extern "C" void -__cxa_vec_delete2 (void *array_address, - std::size_t element_size, - std::size_t padding_size, - void (*destructor) (void *), - void (*dealloc) (void *)) -{ - char *base = static_cast <char *> (array_address); - - if (padding_size) - { - std::size_t element_count = reinterpret_cast <std::size_t *> (base)[-1]; - base -= padding_size; - try - { - __cxa_vec_dtor (array_address, element_count, element_size, - destructor); - } - catch (...) - { + ptr += element_count * element_size; + + try { - uncatch_exception ue; - dealloc (base); + while (ix--) + { + ptr -= element_size; + destructor(ptr); + } } - throw; - } - } - dealloc (base); -} + catch (...) + { + std::terminate(); + } + } + } -extern "C" void -__cxa_vec_delete3 (void *array_address, - std::size_t element_size, - std::size_t padding_size, - void (*destructor) (void *), - void (*dealloc) (void *, std::size_t)) -{ - char *base = static_cast <char *> (array_address); - std::size_t size = 0; + // Destruct and release array. + extern "C" void + __cxa_vec_delete(void *array_address, + std::size_t element_size, + std::size_t padding_size, + void (*destructor) (void *)) + { + __cxa_vec_delete2(array_address, element_size, padding_size, + destructor, + &operator delete []); + } + + extern "C" void + __cxa_vec_delete2(void *array_address, + std::size_t element_size, + std::size_t padding_size, + void (*destructor) (void *), + void (*dealloc) (void *)) + { + char *base = static_cast<char *>(array_address); - if (padding_size) - { - std::size_t element_count = reinterpret_cast <std::size_t *> (base)[-1]; - base -= padding_size; - size = element_count * element_size + padding_size; - try - { - __cxa_vec_dtor (array_address, element_count, element_size, - destructor); - } - catch (...) - { + if (padding_size) + { + std::size_t element_count = reinterpret_cast<std::size_t *>(base)[-1]; + base -= padding_size; + try { - uncatch_exception ue; - dealloc (base, size); + __cxa_vec_dtor(array_address, element_count, element_size, + destructor); } - throw; - } - } - dealloc (base, size); -} + catch (...) + { + { + uncatch_exception ue; + dealloc(base); + } + __throw_exception_again; + } + } + dealloc(base); + } + extern "C" void + __cxa_vec_delete3(void *array_address, + std::size_t element_size, + std::size_t padding_size, + void (*destructor) (void *), + void (*dealloc) (void *, std::size_t)) + { + char *base = static_cast <char *> (array_address); + std::size_t size = 0; + + if (padding_size) + { + std::size_t element_count = reinterpret_cast<std::size_t *> (base)[-1]; + base -= padding_size; + size = element_count * element_size + padding_size; + try + { + __cxa_vec_dtor(array_address, element_count, element_size, + destructor); + } + catch (...) + { + { + uncatch_exception ue; + dealloc(base, size); + } + __throw_exception_again; + } + } + dealloc(base, size); + } } // namespace __cxxabiv1 -#endif // defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 |