platform c++ abi additions

Nick Kledzik kledzik at apple.com
Fri May 14 00:20:09 UTC 2010


I'm exploring adding some new interfaces (described below) to Apple's  
implementation of the C++ ABI.  If there is no interest here in adding  
these to the base C++ ABI, we can add them in a new namespace like  
__cxxabiapple (instead of __cxxabiv1).

As you may have heard, llvm.org is working on a new C++ library  
implementation <http://libcxx.llvm.org/>.  Apple would like to release  
a shared library version of this library (libc++.dylib) in parallel  
with the existing gcc based C++ library (libstc++.dylib).   In order  
to allow these libraries to inter-operate, we plan to factor out the C+ 
+ ABI parts of libstdc++.dylib into a stand alone library (libc+ 
+abi.dylib) which will then be used by the higher level C++ libraries.

But there are a few extra things we need in libc++abi.dylib (beyond  
what the current ABI specifies) to support multiple C++ libraries.  I  
wanted to explain our current implementation to see if this might lead  
to future issues:

1) std::set_terminate(), std::set_unexpected(), and  
std::set_new_handler() assume there is one process wide global holding  
the current handler.   To support this we are adding three global  
variables to libc++abi.dylib:  __cxa_terminate_handler,  
__cxa_unexpected_handler, and __cxa_new_handler.   The two C++  
libraries atop libc++abi.dylib will use these global variables instead  
of having their own copy.

2) C++ 0x introduces std::exception_ptr.  Two years ago on this list,  
Sebastian Redl outlined <http://www.codesourcery.com/archives/cxx-abi-dev/msg01924.html 
 > a way to support exception_ptr by adding a field to __cxa_exception  
and add a similar __cxa_dependent_exception struct.   This  
implementation works, but it exposes some inner workings of libc+ 
+abi.dylib.  It is the only use of __cxa_exception needed in the  
higher level C++ libraries. To provide better encapsulation, we've  
created a procedural interface in  libc++abi.dylib for use by  
exception_ptr:

   extern void * __cxa_current_primary_exception() throw();
   extern void __cxa_rethrow_primary_exception(void* primary_exception);
   extern void __cxa_increment_exception_refcount(void*  
primary_exception) throw();
   extern void __cxa_decrement_exception_refcount(void*  
primary_exception) throw();

These make the implementation of exception_ptr trivial:

   exception_ptr::~exception_ptr()  {
       __cxa_decrement_exception_refcount(__ptr_);
   }

   exception_ptr::exception_ptr(const exception_ptr& other)   : __ptr_ 
(other.__ptr_) {
       __cxa_increment_exception_refcount(__ptr_);
   }

   std::exception_ptr std::current_exception() {
   	return exception_ptr(__cxa_current_primary_exception());
   }

   void std::rethrow_exception(exception_ptr p)  {
	__cxa_rethrow_primary_exception(p.__ptr_);
       std::terminate();
   }

3) Lastly, the only use of __cxa_globals in the higher level C++  
libraries is to implement std::uncaught_exception().  To keep  
__cxa_globals (like __cxa_exception) private to  libc++abi.dylib,  
we've added a new function:

     extern bool __cxa_uncaught_exception() throw();

These new entry points will be in Apple's <cxxabi.h>.  Is there any  
model for platform specific additions to the C++ ABI like these?

-------------
Nick Kledzik
Apple Inc.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://sourcerytools.com/pipermail/cxx-abi-dev/attachments/20100513/6e197263/attachment.html>


More information about the cxx-abi-dev mailing list