[LLVMdev] Catching C++ exceptions, cleaning up, rethrowing
Paul J. Lucas
paul at lucasmail.org
Thu Mar 22 11:40:51 PDT 2012
On Mar 22, 2012, at 12:28 AM, Bill Wendling wrote:
> On Mar 20, 2012, at 7:38 PM, Paul J. Lucas wrote:
>
>> I've read the docs on LLVM exceptions, but I don't see any examples. A little help?
>
> I don't think this has anything to do with LLVM's IR-level exception system. It sounds to me like you just need a way to handle C++ exceptions inside of the C++ code and then rethrow so that the JIT's caller can do its thing. (Right?)
Right. The call sequence is:
my_lib(1) -> JIT_code -> C_thunk -> my_lib(2)
The JIT code creates Functions that create C++ objects on their stacks (by using alloca instructions then calling a C thunk that calls the C++ object's constructor via placement new). If an exception is thrown in my_lib(2), then somewhere between there and when the stack unwinds to my_lib(1), the C++ objects that were created on the stack must have their destructors called (also via C thunks). Hence, some code somewhere between my_lib(1) and C_thunk has to catch all exceptions, call the destructors, and rethrow the exceptions.
> You could move the C++ code into a C++ function that catches all exceptions. The C functions you provide would call the small bit of C++ code that would then execute the "real" functionality. You would have to wrap/unwrap the variables, of course. (There are examples of wrapping/unwrapping of variables in LLVM's source tree.) That way you will get to use C++'s exception handling system instead of creating your own, which is a huge massive undertaking full of pitfalls. When you rethrow the exception, it will propagate past the C function to the code calling the JIT'ed code.
Unfortunately, I'm not following. How is having the code that catches all exceptions in a separate function different from what I proposed (putting the try/catch in the thunks)? (Ideally, I want to minimize layers of function calls.) Again for reference:
extern "C" bool thunk_iterator_M_next( void *v_that, void *v_result,
dtor_pairs *dtors ) {
try {
item_iterator *const that = static_cast<item_iterator*>( v_that );
item *const result = static_cast<item*>( v_result );
return that->next( result );
}
catch ( ... ) {
run_dtors( dtors );
throw;
}
}
- Paul
More information about the llvm-dev
mailing list