source: trunk/src/gcc/libstdc++-v3/libsupc++/vec.cc@ 1465

Last change on this file since 1465 was 2, checked in by bird, 23 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 8.0 KB
Line 
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, <[email protected]>
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
Note: See TracBrowser for help on using the repository browser.