blob: 22a269c6d1dcc89c56c6b53f52ef3d9f2753ba4a [file] [log] [blame]
Marshall Clowe0252022011-07-20 15:04:39 +00001//===------------------------- cxa_exception.cpp --------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//
9// This file implements the "Exception Handling APIs"
10// http://www.codesourcery.com/public/cxx-abi/abi-eh.html
11//
12//===----------------------------------------------------------------------===//
13
14#include "cxxabi.h"
15
16#include <exception> // for std::terminate
17#include <cstdlib> // for malloc, free
18#include <string> // for memset
19#include <pthread.h>
20
21#include "cxa_exception.hpp"
Marshall Clowe0252022011-07-20 15:04:39 +000022
23namespace __cxxabiv1 {
24
25// Utility routines
26static __cxa_exception *exception_from_object ( void *p ) {
27 return ((__cxa_exception *) p ) - 1;
28 }
29
30void * object_from_exception ( void *p ) {
31 return (void *) (((__cxa_exception *) p ) + 1 );
32 }
33
34static size_t object_size_from_exception_size ( size_t size ) {
35 return size + sizeof (__cxa_exception);
36 }
37
38#include "fallback_malloc.cpp"
39
40// Allocate some memory from _somewhere_
41static void *do_malloc ( size_t size ) throw () {
42 void *ptr = std::malloc ( size );
43 if ( NULL == ptr ) // if malloc fails, fall back to emergency stash
44 ptr = fallback_malloc ( size );
45 return ptr;
46 }
47
48// Didn't know you could "return <expression>" from a void function, did you?
49// Well, you can, if the type of the expression is "void" also.
50static void do_free ( void *ptr ) throw () {
51 return is_fallback_ptr ( ptr ) ? fallback_free ( ptr ) : std::free ( ptr );
52 }
53
Marshall Clowe0252022011-07-20 15:04:39 +000054// pthread_once_t __globals::flag_ = PTHREAD_ONCE_INIT;
55
56extern "C" {
57
58// Allocate a __cxa_exception object, and zero-fill it.
59// Reserve "thrown_size" bytes on the end for the user's exception
60// object. Zero-fill the object. If memory can't be allocated, call
61// std::terminate. Return a pointer to the memory to be used for the
62// user's exception object.
63void * __cxa_allocate_exception (size_t thrown_size) throw() {
64 size_t actual_size = object_size_from_exception_size ( thrown_size );
65 void *ptr = do_malloc ( actual_size );
66 if ( NULL == ptr )
67 std::terminate ();
68 std::memset ( ptr, 0, actual_size );
69 return object_from_exception ( ptr );
70 }
71
72
73// Free a __cxa_exception object allocated with __cxa_allocate_exception.
74void __cxa_free_exception (void * thrown_exception) throw() {
75 do_free ( exception_from_object ( thrown_exception ));
76 }
77
78
79// This function shall allocate a __cxa_dependent_exception and
80// return a pointer to it. (Really to the object, not past its' end).
81// Otherwise, it will work like __cxa_allocate_exception.
82void * __cxa_allocate_dependent_exception () throw() {
83 size_t actual_size = sizeof ( __cxa_dependent_exception );
84 void *ptr = do_malloc ( actual_size );
85 if ( NULL == ptr )
86 std::terminate ();
87 std::memset ( ptr, 0, actual_size );
88// bookkeeping here ?
89 return ptr;
90 }
91
92
93// This function shall free a dependent_exception.
94// It does not affect the reference count of the primary exception.
95void __cxa_free_dependent_exception (void * dependent_exception) throw() {
96// I'm pretty sure there's no bookkeeping here
97 do_free ( dependent_exception );
98 }
99
Marshall Clowe0252022011-07-20 15:04:39 +0000100} // extern "C"
101
102} // abi