Marshall Clow | e025202 | 2011-07-20 15:04:39 +0000 | [diff] [blame] | 1 | //===------------------------- 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 Clow | e025202 | 2011-07-20 15:04:39 +0000 | [diff] [blame] | 22 | |
| 23 | namespace __cxxabiv1 { |
| 24 | |
| 25 | // Utility routines |
| 26 | static __cxa_exception *exception_from_object ( void *p ) { |
| 27 | return ((__cxa_exception *) p ) - 1; |
| 28 | } |
| 29 | |
| 30 | void * object_from_exception ( void *p ) { |
| 31 | return (void *) (((__cxa_exception *) p ) + 1 ); |
| 32 | } |
| 33 | |
| 34 | static 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_ |
| 41 | static 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. |
| 50 | static void do_free ( void *ptr ) throw () { |
| 51 | return is_fallback_ptr ( ptr ) ? fallback_free ( ptr ) : std::free ( ptr ); |
| 52 | } |
| 53 | |
Marshall Clow | e025202 | 2011-07-20 15:04:39 +0000 | [diff] [blame] | 54 | // pthread_once_t __globals::flag_ = PTHREAD_ONCE_INIT; |
| 55 | |
| 56 | extern "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. |
| 63 | void * __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. |
| 74 | void __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. |
| 82 | void * __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. |
| 95 | void __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 Clow | e025202 | 2011-07-20 15:04:39 +0000 | [diff] [blame] | 100 | } // extern "C" |
| 101 | |
| 102 | } // abi |