Whole document tree
    

Whole document tree

vec.cc Source File
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 Mon Apr 8 03:11:48 2002 for libstdc++-v3 Source by doxygen1.2.15