[cfe-commits] [libcxxabi] r147106 - in /libcxxabi/trunk: include/cxxabi.h src/cxa_exception.cpp www/spec.html
Howard Hinnant
hhinnant at apple.com
Wed Dec 21 15:32:11 PST 2011
Author: hhinnant
Date: Wed Dec 21 17:32:11 2011
New Revision: 147106
URL: http://llvm.org/viewvc/llvm-project?rev=147106&view=rev
Log:
Added __cxa_increment_exception_refcount, __cxa_decrement_exception_refcount, __cxa_current_primary_exception, __cxa_rethrow_primary_exception
Modified:
libcxxabi/trunk/include/cxxabi.h
libcxxabi/trunk/src/cxa_exception.cpp
libcxxabi/trunk/www/spec.html
Modified: libcxxabi/trunk/include/cxxabi.h
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/include/cxxabi.h?rev=147106&r1=147105&r2=147106&view=diff
==============================================================================
--- libcxxabi/trunk/include/cxxabi.h (original)
+++ libcxxabi/trunk/include/cxxabi.h Wed Dec 21 17:32:11 2011
@@ -155,24 +155,6 @@
size_t* length,
int* status);
- } // extern "C"
-} // namespace __cxxabiv1
-namespace abi = __cxxabiv1;
-
-
-
-
-
-// Below are Apple extensions to support implementing C++ ABI in a seperate dylib
-namespace __cxxabiapple {
- extern "C" {
-
-// Apple additions to support multiple STL stacks that share common
-// terminate, unexpected, and new handlers
-extern void (*__cxa_terminate_handler)();
-extern void (*__cxa_unexpected_handler)();
-extern void (*__cxa_new_handler)();
-
// Apple additions to support C++ 0x exception_ptr class
// These are primitives to wrap a smart pointer around an exception object
extern void * __cxa_current_primary_exception() throw();
@@ -185,6 +167,7 @@
} // extern "C"
} // namespace __cxxabiv1
+namespace abi = __cxxabiv1;
#endif // __cplusplus
Modified: libcxxabi/trunk/src/cxa_exception.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/cxa_exception.cpp?rev=147106&r1=147105&r2=147106&view=diff
==============================================================================
--- libcxxabi/trunk/src/cxa_exception.cpp (original)
+++ libcxxabi/trunk/src/cxa_exception.cpp Wed Dec 21 17:32:11 2011
@@ -287,13 +287,7 @@
}
// Destroy the primary exception only if its referenceCount goes to 0
// (this decrement must be atomic)
- if (__sync_sub_and_fetch(¤t_exception->referenceCount, size_t(1)) == 0)
- {
- void* thrown_object = thrown_object_from_exception(current_exception);
- if (NULL != current_exception->exceptionDestructor)
- current_exception->exceptionDestructor(thrown_object);
- __cxa_free_exception(thrown_object);
- }
+ __cxa_decrement_exception_refcount(thrown_object_from_exception(current_exception));
}
}
}
@@ -347,6 +341,111 @@
failed_throw(exception);
}
+/*
+ If p is not null, atomically increment the referenceCount field of the
+ __cxa_exception header associated with the thrown object referred to by p.
+*/
+void
+__cxa_increment_exception_refcount(void* p) throw()
+{
+ if (p != NULL )
+ {
+ __cxa_exception* header = exception_from_thrown_object(p);
+ __sync_add_and_fetch(&header->referenceCount, 1);
+ }
+}
+
+/*
+ If p is not null, atomically decrement the referenceCount field of the
+ __cxa_exception header associated with the thrown object referred to by p.
+ If the referenceCount drops to zero, destroy and deallocate the exception.
+*/
+void
+__cxa_decrement_exception_refcount(void* thrown_object) throw()
+{
+ if (thrown_object != NULL )
+ {
+ __cxa_exception* header = exception_from_thrown_object(thrown_object);
+ if (__sync_sub_and_fetch(&header->referenceCount, size_t(1)) == 0)
+ {
+ if (NULL != header->exceptionDestructor)
+ header->exceptionDestructor(thrown_object);
+ __cxa_free_exception(thrown_object);
+ }
+ }
+}
+
+/*
+ Returns a pointer to the thrown object (if any) at the top of the
+ caughtExceptions stack. Atommically increment the exception's referenceCount.
+ If there is no such thrown object, returns null.
+*/
+void*
+__cxa_current_primary_exception() throw()
+{
+// get the current exception
+ __cxa_eh_globals* globals = __cxa_get_globals();
+ __cxa_exception* current_exception = globals->caughtExceptions;
+ if (NULL == current_exception)
+ return NULL; // No current exception
+ if (isDependentException(¤t_exception->unwindHeader)) {
+ __cxa_dependent_exception* deh =
+ reinterpret_cast<__cxa_dependent_exception*>(current_exception + 1) - 1;
+ current_exception = static_cast<__cxa_exception*>(deh->primaryException) - 1;
+ }
+ void* thrown_object = thrown_object_from_exception(current_exception);
+ __cxa_increment_exception_refcount(thrown_object);
+ return thrown_object;
+}
+
+/*
+ If reason isn't _URC_FOREIGN_EXCEPTION_CAUGHT, then the terminateHandler
+ stored in exc is called. Otherwise the referenceCount stored in the
+ primary exception is decremented, destroying the primary if necessary.
+ Finally the dependent exception is destroyed.
+*/
+static
+void
+dependent_exception_cleanup(_Unwind_Reason_Code reason, struct _Unwind_Exception* exc)
+{
+ __cxa_dependent_exception* deh =
+ reinterpret_cast<__cxa_dependent_exception*>(exc + 1) - 1;
+ if (_URC_FOREIGN_EXCEPTION_CAUGHT != reason)
+ std::__terminate(deh->terminateHandler);
+ __cxa_decrement_exception_refcount(deh->primaryException);
+ __cxa_free_dependent_exception(deh);
+}
+
+/*
+ If thrown_object is not null, allocate, initialize and thow a dependent
+ exception.
+*/
+void
+__cxa_rethrow_primary_exception(void* thrown_object)
+{
+ if ( thrown_object != NULL )
+ {
+ __cxa_exception* header = exception_from_thrown_object(thrown_object);
+ __cxa_dependent_exception* deh =
+ (__cxa_dependent_exception*)__cxa_allocate_dependent_exception();
+ deh->primaryException = thrown_object;
+ __cxa_increment_exception_refcount(thrown_object);
+ deh->exceptionType = header->exceptionType;
+ deh->unexpectedHandler = std::get_unexpected();
+ deh->terminateHandler = std::get_terminate();
+ setDependentExceptionClass(&deh->unwindHeader);
+ deh->unwindHeader.exception_cleanup = dependent_exception_cleanup;
+#if __arm__
+ _Unwind_SjLj_RaiseException(&deh->unwindHeader);
+#else
+ _Unwind_RaiseException(&deh->unwindHeader);
+#endif
+ // Some sort of unwinding error. Note that terminate is a handler.
+ __cxa_begin_catch(&deh->unwindHeader);
+ }
+ // If we return client will call terminate()
+}
+
} // extern "C"
} // abi
Modified: libcxxabi/trunk/www/spec.html
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/www/spec.html?rev=147106&r1=147105&r2=147106&view=diff
==============================================================================
--- libcxxabi/trunk/www/spec.html (original)
+++ libcxxabi/trunk/www/spec.html Wed Dec 21 17:32:11 2011
@@ -248,9 +248,9 @@
</p>
</blockquote>
</td>
-<td></td>
-<td></td>
-<td></td>
+<td>✓</td>
+<td>✓</td>
+<td>✓</td>
</tr>
<tr>
@@ -265,9 +265,9 @@
</p>
</blockquote>
</td>
-<td></td>
-<td></td>
-<td></td>
+<td>✓</td>
+<td>✓</td>
+<td>✓</td>
</tr>
<tr>
@@ -319,9 +319,9 @@
</p>
</blockquote>
</td>
-<td></td>
-<td></td>
-<td></td>
+<td>✓</td>
+<td>✓</td>
+<td>✓</td>
</tr>
<tr>
@@ -335,9 +335,9 @@
</p>
</blockquote>
</td>
-<td></td>
-<td></td>
-<td></td>
+<td>✓</td>
+<td>✓</td>
+<td>✓</td>
</tr>
<tr>
@@ -675,9 +675,9 @@
</p>
</blockquote>
</td>
-<td></td>
-<td></td>
-<td></td>
+<td>✓</td>
+<td>✓</td>
+<td>✓</td>
</tr>
<tr>
@@ -691,9 +691,9 @@
</p>
</blockquote>
</td>
-<td></td>
-<td></td>
-<td></td>
+<td>✓</td>
+<td>✓</td>
+<td>✓</td>
</tr>
<tr>
@@ -707,9 +707,9 @@
</p>
</blockquote>
</td>
-<td></td>
-<td></td>
-<td></td>
+<td>✓</td>
+<td>✓</td>
+<td>✓</td>
</tr>
More information about the cfe-commits
mailing list