[LLVMdev] How to initiate/throw an exception (resume just continues)
David.Chisnall at cl.cam.ac.uk
Fri Mar 29 10:34:54 PDT 2013
On 29 Mar 2013, at 17:15, edA-qa mort-ora-y <eda-qa at disemia.com> wrote:
> I'm trying to add some basic exception handling to my language now and
> I'm uncertain of how I actually start the exception propagation. It
> appears that "resume" will continue the exception, but I see no mention
> of how the exception actually starts.
> If I look at the IR output of a simple C++ program I see that it calls
> @__cxa_throw, but that is a library function. Somehow I must be able to
> initiate the exception in LLVM?
Yes, by calling a library function. You will need to implement this for your language, along with a personality function (or reuse ones from some existing language). The __cxa_throw() function is responsible for allocating an exception structure that contains two things, the C++ information (such as the thrown object, its type_info, the current values of the terminate and unexpected handlers, and so on), and a generic structure for the unwind library. It then passes it to _Unwind_RaiseException(), which is the generic unwind routine.
The _Unwind_RaiseException() function walks up the stack, invoking the personality routine once to find a landing pad for a catch. If it fails to find one then it returns an error. If it succeeds, then it invokes them again to run cleanup code. The personality function is passed the thrown object and also a reference to the language-specific data area. This area is filled in by LLVM via landingpad instructions.
The resume instruction is just a convenience. It will be expanded to a call to another library function (_Unwind_Resume(), I think, but possible _Unwind_ResumeOrRethrow()), and it exists so that the IR doesn't have to have hard-coded knowledge of the semantics of one these functions.
The exact implementation of the personality function differs slightly between ARM and pretty much everything else for *NIX platforms. Win64 also has a very similar mechanism for exceptions, but I don't believe it is currently supported by LLVM. ARM now works in some cases, but is still quite buggy.
The personality function is probably the least fun code I've ever written (I've now done it three times, for three different languages, and it doesn't become any more fun). If you get it wrong, the stack is gone by the time you get into the debugger, so lots and lots of logging statements are your friend...
More information about the llvm-dev