<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sat, May 16, 2015 at 7:29 AM, Steve Cheng <span dir="ltr"><<a href="mailto:steve.ckp@gmail.com" target="_blank">steve.ckp@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On 2015-05-15 18:37:58 -0400, Reid Kleckner said:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
After a long tale of sorrow and woe, my colleagues and I stand here before you defeated. The Itanium EH representation is not amenable to implementing MSVC-compatible exceptions. We need a new representation that preserves information about how try-catch blocks are nested.<br>
</blockquote>
<br></span>
Hi,<br>
<br>
Newbie here. This must be a dumb question, but it's not something I can understand from reading the design documents and RFCs.<br>
<br>
Why don't we write and use our own personality function, and then we avoid all these restrictions on the interval tables? On Windows, we would still have to catch exceptions with SEH, of course. But SEH should be language-independent, in the sense that it concerns only unwinding for the "low level" parts of the ABI, like restoring non-volatile registers. It doesn't seem to make sense that LLVM, being a language-independent IR, should concern itself with personality functions specific to Microsoft's C++ run-time library.<br>
<br>
I understand we want to link compatibility with object code from Visual Studio, but I didn't think that the personality-specific unwind tables were actually an ABI "artifact". I mean, let's say you compile a function in Visual Studio, the result is a function with some mangled symbol that other object code can make references through the linker. But the other object code never incestuously refers to the unwind tables of the function it calls, right?<br>
<br>
I'm speaking from the point of view of an implementor of a new programming language who wants to interoperate with C++. I've already got code that can decode the Microsoft RTTI info coming from C++ exceptions, and the pointers to those can be extracted with SEH GetExceptionPointers, etc. To support catching exceptions in my language, or at least calling cleanups while unwinding, I really don't care about the C++ personality function. After all my language might not even have the concept of (nested) try/catch blocks. The custom personality function does have to be supplied as part of the run-time, but as a frontend implementor I'm prepared to have to write a run-time anyway.<br></blockquote><div><br></div><div>Right, doing our own personality function is possible, but still has half the challenge of using __CxxFrameHandler3, and introduces a new runtime dependency that isn't there currently. Given that it won't save that much work, I'd rather not introduce a dependency that wasn't there before.</div><div><br></div><div>The reason it's still hard is that you have to split the main function up into more than one subfunction. The exception object is allocated in the frame of the function calling __CxxThrow, and it has to stay alive until control leaves the catch block receiving the exception. This is different from Itanium, where the exception object is constructed in heap memory and the pointer is saved in TLS. If this were not the case, we'd use the __gxx_personaltity_v0-style landingpad approach and make a new personality variant that understands MS RTTI.</div><div><br></div><div>We could try to do all this outlining in Clang, but that blocks a lot of LLVM optimizations. Any object with a destructor (std::string) is now escaped into the funclet that calls the destructor, and simple transformations (SROA) require interprocedural analysis. This affects the code on the normal code path and not just the exceptional path. While EH constructs like try / catch are fairly rare in C++, destructor cleanups are very, very common, and I'd rather not pessimize so much code.</div></div></div></div>