Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

vec.cc

Go to the documentation of this file.
00001 // New abi Support -*- C++ -*-
00002 
00003 // Copyright (C) 2000, 2001 Free Software Foundation, Inc.
00004 //  
00005 // This file is part of GNU CC.
00006 //
00007 // GNU CC is free software; you can redistribute it and/or modify
00008 // it under the terms of the GNU General Public License as published by
00009 // the Free Software Foundation; either version 2, or (at your option)
00010 // any later version.
00011 
00012 // GNU CC is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 
00017 // You should have received a copy of the GNU General Public License
00018 // along with GNU CC; see the file COPYING.  If not, write to
00019 // the Free Software Foundation, 59 Temple Place - Suite 330,
00020 // Boston, MA 02111-1307, USA. 
00021 
00022 // As a special exception, you may use this file as part of a free software
00023 // library without restriction.  Specifically, if other files instantiate
00024 // templates or use macros or inline functions from this file, or you compile
00025 // this file and link it with other files to produce an executable, this
00026 // file does not by itself cause the resulting executable to be covered by
00027 // the GNU General Public License.  This exception does not however
00028 // invalidate any other reasons why the executable file might be covered by
00029 // the GNU General Public License.
00030 
00031 // Written by Nathan Sidwell, Codesourcery LLC, <nathan@codesourcery.com>
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   // Allocate and construct array.
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   // Construct array.
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   // Construct an array by copying.
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   // Destruct array.
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   // Destruct array as a result of throwing an exception.
00233   // [except.ctor]/3 If a destructor called during stack unwinding
00234   // exits with an exception, terminate is called.
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   // Destruct and release array.
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 } // namespace __cxxabiv1
00337 

Generated on Sat Apr 19 07:14:35 2003 for libstdc++-v3 Source by doxygen1.2.15