Well that clears up a little bit of the mystery - thanks for doing that research.<div><br></div><div>I recognize the problem with runtime libraries for LLVM. I am in fact writing a generic runtime library as part of the garbage collector work I am doing - it uses policy-based templates so that things like the threading model, atomic operations and error reporting can all be replaced by the host environment as needed.</div>
<div><br></div><div>That being said, my immediate problem is still getting exceptions to work.</div><div><br></div><div>The biggest problem that I foresee with writing my own personality function is dealing with all of the different platforms. Both LLVM and glibc isolate me to some extent from platform idiosyncracies, meaning that I can for the most part code against a platform-agnostic API and not worry about it. However, the innards of glibc are no doubt radically different between platforms, which will bring me a world of pain if I attempt to replace parts of it.</div>
<div><br></div><div>On the other hand, at some point I was going to have to do this anyway, given that I wanted to support compiling under MSVC as well as GCC eventually. I feel that LLVM relies too heavily on functionality provided by glibc, but I recognize that for most of the people working on it, that option makes the most sense and meets their needs.</div>
<div><br></div><div>I don't actually think that LLVM needs its own standard personality function per se. I think what it needs is a few additional intrinsics that will allow someone like me to write a personality function. An example would be intrinsics that wrap around the various libunwind methods, but which hide the specific platform details like register numbers and such.</div>
<div><br></div><div>How complex do you think a standard personality function would likely be? This is kind of hard for me to guess, since I don't quite understand the division of labor between the personality function and the landing pad (I get the impression its flexible).</div>
<div><br></div><div>I can think of several ways in which a personality function might work:</div><div><br></div><div>1) The personality function examines the type of the exception object and determines what label to branch to in the function containing the handler. The biggest problem with this is that there's no way for the personality function to take a reference to a label at the IR level.</div>
<div><br></div><div>2) The personality function examines the type of the exception object, and returns an integer code telling the landing pad where to branch to. The landing pad does a switch instruction and branches to the correct label. The problem here is that passing values between the personality function and the landing pad cannot be done at the IR level without knowing intimate details about the platform.</div>
<div><br></div><div>3) The personality function merely returns true or false, indicating an exception was caught or not - it's the landing pad's responsibility to examine the exception type and branch accordingly. This type of personality function would be relatively simple (if it worked) and completely generic. At the same time, however, it is potentially the least efficient, since it cannot make use of any of the jump table information generated by the compiler, nor can it determine if the exception was in fact caught - it has to assume that the exception was always caught, and then if the landing pad later determines that there was no catch clause for that particular exception type, then it has to rethrow it. (Note, I have no idea whether or not either of these issues are in any way significant, since I don't know what kind of code the compiler generates.)</div>
<div><br></div><div><div class="gmail_quote">On Thu, May 21, 2009 at 1:16 AM, Duncan Sands <span dir="ltr"><<a href="mailto:baldrick@free.fr" target="_blank">baldrick@free.fr</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Talin, if you change @throwSomething so that it prints a message<br>
if the _Unwind_RaiseException call returns, then you will see that<br>
it does in fact return.<br>
<br>
define internal fastcc void @throwSomething() {<br>
entry:<br>
         %throwable = malloc %Throwable<br>
         call fastcc void @Throwable.construct(%Throwable* %throwable)<br>
         %unwindInfo = getelementptr %Throwable* %throwable, i32 0, i32 1<br>
         call void @print(i8* bitcast ([6 x i8]* @str_throw to i8 *))<br>
         %throw = call i32 @_Unwind_RaiseException(%UnwindInfo* %unwindInfo)<br>
         call void @print(i8* bitcast ([6 x i8]* @str_abort to i8 *))<br>
         ret void<br>
}<br>
<br>
This is because it unwound the stack without finding any exception<br>
handlers.  It doesn't consider your exception handler to be a handler<br>
because it is registered as a "cleanup" which apparently doesn't count.<br>
(To force cleanups to be run in this situation you have to call the gcc<br>
forced unwind routine after calling Unwind_RaiseException).<br>
<br>
Of course you would probably like to have your handler be considered a<br>
real handler.  Sadly you can't use __gcc_personality_v0 for this: it<br>
only handles cleanups, and if it sees something else (eg: if you specify<br>
a catch-all in the selector) then it tells the unwinder to keep on<br>
unwinding, which is not what you want.<br>
<br>
So indeed you either need to write your own personality routine or use<br>
a more powerful personality function like the C++ personality, and use<br>
an eh.selector call to specify a catch-all (use null for this).<br>
<br>
In order to get correct invoke semantics, LLVM really needs its own<br>
personality function.  The problem is that LLVM doesn't have its own<br>
runtime library like libgcc.  This could be overcome by outputting the<br>
LLVM personality into each assembler file that needs it, with weak<br>
linkage so that multiple copies get collapsed to one at link time.<br>
<div><div></div><div><br>
Ciao,<br>
<br>
Duncan.<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
</div></div></blockquote></div><br><br clear="all"><br>-- <br>-- Talin<br>
</div>