digitalmars.D - Catching C++ std::exception in D
- Walter Bright (39/39) Nov 11 2015 In order to interoperate with modern C++, it has been abundantly clear f...
- krzaq (5/9) Nov 11 2015 What about rethrowing C++ exceptions? Are we going to use pointer
- Kagamin (3/6) Nov 11 2015 std::exception is class, i.e. reference type, so you won't be
- krzaq (3/9) Nov 11 2015 Sure, but it's idiomatic to catch by reference, hence the
- Iain Buclaw via Digitalmars-d (24/53) Nov 12 2015 Support for 1 and 2 already exists, and comes for free it you are using
- Walter Bright (4/10) Nov 12 2015 It only has a different name. Not a different API.
- Iain Buclaw via Digitalmars-d (4/14) Nov 12 2015 Correct, there is no way out of having one.
- Johannes Pfau (11/38) Nov 12 2015 To expand on this: I think we'd prefer one __d_personality_v0 which is
- Dan Olson (11/13) Nov 12 2015 Speacking of upstream support. GDC support SjLj exceptions. In 2.067,
- Johannes Pfau (5/22) Nov 12 2015 Nice work. We certainly want that in GDC or even better in upstream.
- Dan Olson (5/27) Nov 13 2015 I had 2.067 unittest failures without this change, I don't recall which.
- Iain Buclaw via Digitalmars-d (4/34) Nov 13 2015 There may be a few other holes between how Fibers and EH interact.
- David Nadlinger (4/7) Nov 14 2015 The SJLJ stack switching should probably be added to this
- Dan Olson (5/11) Nov 14 2015 I did a quick experiment to merge the two approaches and it failed in
- Dan Olson (6/35) Nov 14 2015 I removed my SjLj change in core.thread to see what fails.
- David Nadlinger (10/22) Nov 12 2015 It should probably be based on the LDC implementation then, as it
- Jacob Carlborg (8/10) Nov 12 2015 In would be nice if we were able to catch Objective-C exceptions as well...
- Iain Buclaw via Digitalmars-d (10/21) Nov 12 2015 C++ can catch exceptions thrown in D and ObjC using `catch(...)`, and
- Walter Bright (2/7) Nov 12 2015 I don't anticipate that would be too difficult to add.
- Jacob Carlborg (4/5) Nov 12 2015 Great :)
- Iain Buclaw via Digitalmars-d (5/11) Nov 12 2015 I'll have to check, but I'm pretty certain that libunwind will call the ...
- Walter Bright (3/10) Nov 12 2015 Why should it? What tells libunwind to call the C++ personality function...
- deadalnix (3/20) Nov 12 2015 The personality function is in the landingpad metadata. Why would
- Iain Buclaw via Digitalmars-d (4/24) Nov 12 2015 I did say that I'd have to check. :-)
- Jacob Carlborg (7/8) Nov 12 2015 Objective-C does that [1].
- deadalnix (3/9) Nov 12 2015 ObjC doesn't do cleanup, so that's a bit different.
- Elie Morisse (18/33) Nov 12 2015 I also started working on C++ exception handling for LDC/Calypso,
- David Nadlinger (15/18) Nov 12 2015 This should be rather simple; you know it is C++ because of the
- Elie Morisse (20/20) Nov 14 2015 Sorry for the delay, here's the initial commit for C++ exception
In order to interoperate with modern C++, it has been abundantly clear for some time that D needs some support for C++ exception handling: 1. Have D finally blocks executed in D code that sits between a C++ try and catch 2. Have C++ finally blocks executed in C++ code that sits between a D try and catch 3. Be able to catch in D code an std::exception* or a C++ class derived from that. 4. Throw an std::exception* from D code. That's the minimum credible support, and is likely all D will actually need. It's also clear that over the years nobody has risen to the challenge to get this working in dmd, so it falls to me to do it: https://www.youtube.com/watch?feature=player_detailpage&v=Nglh-BExEus#t=227 :-) The Current State ----------------- Win32: DMC++ and DMD use standard Windows SEH, so this should be fairly easy to get to work. Unfortunately, Win32 is the past. Win64: VC++ uses some bizarre unique scheme. I have no idea how it works. DMD uses the DM scheme I invented 30 years ago (!) that is very simple and works great, though it does have some performance penalties in the non-EH path. Linux, OSX, FreeBSD: g++/clang++ use the dwarf eh scheme. DMD uses the DM scheme. Action Plan ----------- Switch to using dwarf eh on Linux 64 (our most important platform). Once that works, it can be easily (hopefully) extended to the other dwarf eh platforms. Eventually, figure out the V++ Win64 scheme. Progress -------- I have started by switching from generating .debug_frame sections to .eh_frame sections. It appears that gcc/g++ already do this, and .debug_frame is now obsolete. I'll pretty much have to generate .gcc_except_table myself, as well as redo how the finally and catch block code is generated. Can Really Use Help ------------------- I really appreciate the offers, and here's what will really help: Writing the druntime end of things, which is really providing just two functions: d_throw (d_dwarf_throw to distinguish it) and the libunwind personality function: __dmd_personality_v0. The tricky part with the personality function will likely be recognizing std::exception* exceptions. I wonder if forwarding the call to __gxx_personality_v0 will work. Work on this should be independent of the dmd compiler changes.
Nov 11 2015
On Thursday, 12 November 2015 at 06:50:31 UTC, Walter Bright wrote:In order to interoperate with modern C++, it has been abundantly clear for some time that D needs some support for C++ exception handling: [...]What about rethrowing C++ exceptions? Are we going to use pointer notation for C++ exceptions? This may be the same under the hood, but looks way different.
Nov 11 2015
On Thursday, 12 November 2015 at 07:00:43 UTC, krzaq wrote:What about rethrowing C++ exceptions? Are we going to use pointer notation for C++ exceptions? This may be the same under the hood, but looks way different.std::exception is class, i.e. reference type, so you won't be able to throw or catch it by value in D anyway.
Nov 11 2015
On Thursday, 12 November 2015 at 07:47:16 UTC, Kagamin wrote:On Thursday, 12 November 2015 at 07:00:43 UTC, krzaq wrote:Sure, but it's idiomatic to catch by reference, hence the question.What about rethrowing C++ exceptions? Are we going to use pointer notation for C++ exceptions? This may be the same under the hood, but looks way different.std::exception is class, i.e. reference type, so you won't be able to throw or catch it by value in D anyway.
Nov 11 2015
On 12 November 2015 at 07:50, Walter Bright via Digitalmars-d < digitalmars-d puremagic.com> wrote:In order to interoperate with modern C++, it has been abundantly clear for some time that D needs some support for C++ exception handling: 1. Have D finally blocks executed in D code that sits between a C++ try and catch 2. Have C++ finally blocks executed in C++ code that sits between a D try and catch 3. Be able to catch in D code an std::exception* or a C++ class derived from that. 4. Throw an std::exception* from D code. That's the minimum credible support, and is likely all D will actually need. It's also clear that over the years nobody has risen to the challenge to get this working in dmd, so it falls to me to do it: https://www.youtube.com/watch?feature=player_detailpage&v=Nglh-BExEus#t=227 :-)Support for 1 and 2 already exists, and comes for free it you are using libunwind, all what is needed is a little assistance to make it realised. Though it also helps if you have some supporting backend to generate the magic EH handling for you too. :-) Having your own EH tables has really left you with a shotgun wound in the foot here. I suspect this is the real reason why no one has stepped up. Progress-------- I have started by switching from generating .debug_frame sections to .eh_frame sections. It appears that gcc/g++ already do this, and .debug_frame is now obsolete. I'll pretty much have to generate .gcc_except_table myself, as well as redo how the finally and catch block code is generated.Good luck! Just a small request to on my side to not introduce anything in the frontend! I don't want a repeat of __va_argsave where gdc had supported 64bit for years and years.Can Really Use Help ------------------- I really appreciate the offers, and here's what will really help: Writing the druntime end of things, which is really providing just two functions: d_throw (d_dwarf_throw to distinguish it) and the libunwind personality function: __dmd_personality_v0. The tricky part with the personality function will likely be recognizing std::exception* exceptions. I wonder if forwarding the call to __gxx_personality_v0 will work.I don't mind the compiler-specific personality, but a new throw function? I guess I should count my lucky stars that I'm still using the original _d_throw callback. You will be able to recognize whether or not the exception object comes from C++, unwind's exception_class field can be compared to some gxx_exception_class enum value (or const symbol). Getting the typeinfo of the C++ exception is straightforward too. In the EH table, I guess you will have to generate an extern reference to C++'s typeinfo object somehow... -- Regards Iain
Nov 12 2015
On 11/12/2015 12:57 AM, Iain Buclaw via Digitalmars-d wrote:I don't mind the compiler-specific personality,gdc has one, __gcd_personality_v0. I don't see a way out of not having one.but a new throw function? I guess I should count my lucky stars that I'm still using the original _d_throw callback.It only has a different name. Not a different API.In the EH table, I guess you will have to generate an extern reference to C++'s typeinfo object somehow...That shouldn't be difficult.
Nov 12 2015
On 12 November 2015 at 10:36, Walter Bright via Digitalmars-d < digitalmars-d puremagic.com> wrote:On 11/12/2015 12:57 AM, Iain Buclaw via Digitalmars-d wrote:Correct, there is no way out of having one.I don't mind the compiler-specific personality,gdc has one, __gcd_personality_v0. I don't see a way out of not having one.but a new throw function? IIt's just more ABI differences between D compilers. ;-)guess I should count my lucky stars that I'm still using the original _d_throw callback.It only has a different name. Not a different API.
Nov 12 2015
Am Thu, 12 Nov 2015 11:31:39 +0100 schrieb Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com>:On 12 November 2015 at 10:36, Walter Bright via Digitalmars-d < digitalmars-d puremagic.com> wrote:To expand on this: I think we'd prefer one __d_personality_v0 which is implemented in upstream druntime and identical for all compilers. Making the compilers ABI compatible is probably not a high priority, but OTOH we shouldn't introduce new ABI incompatibilities if possible. Think of it this way: At some point it would be nice to have one, system-wide installed druntime shared library (from any compiler) and programs compiled with any other compiler should be able to use it. We've got well-defined name mangling primarily to allow this - but because of many small differences mixing compilers is not possible yet.On 11/12/2015 12:57 AM, Iain Buclaw via Digitalmars-d wrote:Correct, there is no way out of having one.I don't mind the compiler-specific personality,gdc has one, __gcd_personality_v0. I don't see a way out of not having one.but a new throw function? IIt's just more ABI differences between D compilers. ;-)guess I should count my lucky stars that I'm still using the original _d_throw callback.It only has a different name. Not a different API.
Nov 12 2015
Johannes Pfau <nospam example.com> writes:To expand on this: I think we'd prefer one __d_personality_v0 which is implemented in upstream druntime and identical for all compilers.Speacking of upstream support. GDC support SjLj exceptions. In 2.067, it became obvious that Fiber needed separate SjLj context stacks which are normally thread specific. I have a change in my iOS LDC fork which I suppose could go to upstream thread.d file so GDC can pick it up to. https://github.com/smolt/druntime/commit/5d32e9e68cc6bd8b13cacfdb18a4d91374bf6b3e See, I even included GNU_SjLj_Exceptions :-) Sound like a good idea? It is getting queued up soon as a PR to LDC once we get an iOS version officially in the compiler frontend. -- Dan
Nov 12 2015
Am Thu, 12 Nov 2015 09:59:14 -0800 schrieb Dan Olson <gorox comcast.net>:Johannes Pfau <nospam example.com> writes:Nice work. We certainly want that in GDC or even better in upstream. I guess we don't have a unittest yet which can detect this problem. Is it possible to add a unittest for this?To expand on this: I think we'd prefer one __d_personality_v0 which is implemented in upstream druntime and identical for all compilers.Speacking of upstream support. GDC support SjLj exceptions. In 2.067, it became obvious that Fiber needed separate SjLj context stacks which are normally thread specific. I have a change in my iOS LDC fork which I suppose could go to upstream thread.d file so GDC can pick it up to. https://github.com/smolt/druntime/commit/5d32e9e68cc6bd8b13cacfdb18a4d91374bf6b3e See, I even included GNU_SjLj_Exceptions :-) Sound like a good idea? It is getting queued up soon as a PR to LDC once we get an iOS version officially in the compiler frontend.
Nov 12 2015
Johannes Pfau <nospam example.com> writes:Am Thu, 12 Nov 2015 09:59:14 -0800 schrieb Dan Olson <gorox comcast.net>:I had 2.067 unittest failures without this change, I don't recall which. I know it made me laugh becase exceptions were being thrown from Fiber A but being caught by Fiber B. I can easily find out what fails by rerunning without the change. I'll report back later.Johannes Pfau <nospam example.com> writes:Nice work. We certainly want that in GDC or even better in upstream. I guess we don't have a unittest yet which can detect this problem. Is it possible to add a unittest for this?To expand on this: I think we'd prefer one __d_personality_v0 which is implemented in upstream druntime and identical for all compilers.Speacking of upstream support. GDC support SjLj exceptions. In 2.067, it became obvious that Fiber needed separate SjLj context stacks which are normally thread specific. I have a change in my iOS LDC fork which I suppose could go to upstream thread.d file so GDC can pick it up to. https://github.com/smolt/druntime/commit/5d32e9e68cc6bd8b13cacfdb18a4d91374bf6b3e See, I even included GNU_SjLj_Exceptions :-) Sound like a good idea? It is getting queued up soon as a PR to LDC once we get an iOS version officially in the compiler frontend.
Nov 13 2015
On 13 November 2015 at 18:45, Dan Olson via Digitalmars-d < digitalmars-d puremagic.com> wrote:Johannes Pfau <nospam example.com> writes:There may be a few other holes between how Fibers and EH interact. https://github.com/D-Programming-Language/druntime/commit/f6633abb43ea1f2464d3a772b8f8fe78216ffd8eAm Thu, 12 Nov 2015 09:59:14 -0800 schrieb Dan Olson <gorox comcast.net>:https://github.com/smolt/druntime/commit/5d32e9e68cc6bd8b13cacfdb18a4d91374bf6b3eJohannes Pfau <nospam example.com> writes:To expand on this: I think we'd prefer one __d_personality_v0 which is implemented in upstream druntime and identical for all compilers.Speacking of upstream support. GDC support SjLj exceptions. In 2.067, it became obvious that Fiber needed separate SjLj context stacks which are normally thread specific. I have a change in my iOS LDC fork which I suppose could go to upstream thread.d file so GDC can pick it up to.I had 2.067 unittest failures without this change, I don't recall which. I know it made me laugh becase exceptions were being thrown from Fiber A but being caught by Fiber B. I can easily find out what fails by rerunning without the change. I'll report back later.See, I even included GNU_SjLj_Exceptions :-) Sound like a good idea? It is getting queued up soon as a PR to LDC once we get an iOS version officially in the compiler frontend.Nice work. We certainly want that in GDC or even better in upstream. I guess we don't have a unittest yet which can detect this problem. Is it possible to add a unittest for this?
Nov 13 2015
On Friday, 13 November 2015 at 18:40:06 UTC, Iain Buclaw wrote:There may be a few other holes between how Fibers and EH interact. https://github.com/D-Programming-Language/druntime/commit/f6633abb43ea1f2464d3a772b8f8fe78216ffd8eThe SJLJ stack switching should probably be added to this mechanism. — David
Nov 14 2015
David Nadlinger <code klickverbot.at> writes:On Friday, 13 November 2015 at 18:40:06 UTC, Iain Buclaw wrote:I did a quick experiment to merge the two approaches and it failed in unittests. I am not sure why yet. They are implemented slightly different in that SjLj context is saved in the Fiber object, whereas _d_eh_swapContext is saving in a Thread.Context object.There may be a few other holes between how Fibers and EH interact. https://github.com/D-Programming-Language/druntime/commit/f6633abb43ea1f2464d3a772b8f8fe78216ffd8eThe SJLJ stack switching should probably be added to this mechanism. — David
Nov 14 2015
Dan Olson <gorox comcast.net> writes:Johannes Pfau <nospam example.com> writes:I removed my SjLj change in core.thread to see what fails. Running 2.067 unittests, std.concurrency fails with a memory access error. Latest core.thread has a unittest for "Test exception chaining when switching contexts in finally blocks" that also fails with a memory access error.Am Thu, 12 Nov 2015 09:59:14 -0800 schrieb Dan Olson <gorox comcast.net>:I had 2.067 unittest failures without this change, I don't recall which. I know it made me laugh becase exceptions were being thrown from Fiber A but being caught by Fiber B. I can easily find out what fails by rerunning without the change. I'll report back later.Johannes Pfau <nospam example.com> writes:Nice work. We certainly want that in GDC or even better in upstream. I guess we don't have a unittest yet which can detect this problem. Is it possible to add a unittest for this?To expand on this: I think we'd prefer one __d_personality_v0 which is implemented in upstream druntime and identical for all compilers.Speacking of upstream support. GDC support SjLj exceptions. In 2.067, it became obvious that Fiber needed separate SjLj context stacks which are normally thread specific. I have a change in my iOS LDC fork which I suppose could go to upstream thread.d file so GDC can pick it up to. https://github.com/smolt/druntime/commit/5d32e9e68cc6bd8b13cacfdb18a4d91374bf6b3e See, I even included GNU_SjLj_Exceptions :-) Sound like a good idea? It is getting queued up soon as a PR to LDC once we get an iOS version officially in the compiler frontend.
Nov 14 2015
On Thursday, 12 November 2015 at 16:55:09 UTC, Johannes Pfau wrote:To expand on this: I think we'd prefer one __d_personality_v0 which is implemented in upstream druntime and identical for all compilers. Making the compilers ABI compatible is probably not a high priority, but OTOH we shouldn't introduce new ABI incompatibilities if possible.It should probably be based on the LDC implementation then, as it supports the most target platforms (Posix/libunwind, Win64/MSVC, iOS/SJLJ, and, as work in progress, Win32/SEH) and GDC's implementation is probably GPL-licensed (with runtime exceptions, but still definitely not Boost-compatible).Think of it this way: At some point it would be nice to have one, system-wide installed druntime shared library (from any compiler) and programs compiled with any other compiler should be able to use it. We've got well-defined name mangling primarily to allow this - but because of many small differences mixing compilers is not possible yet.The biggest of which is probably that GDC and DMD disagree on parameter passing orders. — David
Nov 12 2015
On 2015-11-12 07:50, Walter Bright wrote:3. Be able to catch in D code an std::exception* or a C++ class derived from that.In would be nice if we were able to catch Objective-C exceptions as well (it uses the same exception handling as C++). They have their own tree of exception classes which do not inherit from std::exception. We don't need to support this right away but it would be nice to avoid any artificial limitations preventing this. -- /Jacob Carlborg
Nov 12 2015
On 12 November 2015 at 09:59, Jacob Carlborg via Digitalmars-d < digitalmars-d puremagic.com> wrote:On 2015-11-12 07:50, Walter Bright wrote: 3. Be able to catch in D code an std::exception* or a C++ class derivedC++ can catch exceptions thrown in D and ObjC using `catch(...)`, and there's no technical limitation on why we can't do the same from a D `catch { }`. But I don't think Walter wants C++-style catch-all support in D, and currently our version of catch-all is lowered to `catch(Throwable)` which does not have the same semantic meaning. -- Regards Iainfrom that.In would be nice if we were able to catch Objective-C exceptions as well (it uses the same exception handling as C++). They have their own tree of exception classes which do not inherit from std::exception. We don't need to support this right away but it would be nice to avoid any artificial limitations preventing this. -- /Jacob Carlborg
Nov 12 2015
On 11/12/2015 12:59 AM, Jacob Carlborg wrote:In would be nice if we were able to catch Objective-C exceptions as well (it uses the same exception handling as C++). They have their own tree of exception classes which do not inherit from std::exception. We don't need to support this right away but it would be nice to avoid any artificial limitations preventing this.I don't anticipate that would be too difficult to add.
Nov 12 2015
On 2015-11-12 10:40, Walter Bright wrote:I don't anticipate that would be too difficult to add.Great :) -- /Jacob Carlborg
Nov 12 2015
On 12 November 2015 at 07:50, Walter Bright via Digitalmars-d < digitalmars-d puremagic.com> wrote:I really appreciate the offers, and here's what will really help: Writing the druntime end of things, which is really providing just two functions: d_throw (d_dwarf_throw to distinguish it) and the libunwind personality function: __dmd_personality_v0. The tricky part with the personality function will likely be recognizing std::exception* exceptions. I wonder if forwarding the call to __gxx_personality_v0 will work.I'll have to check, but I'm pretty certain that libunwind will call the C++ personality for you if you return `nothing found` from D personality function.
Nov 12 2015
On 11/12/2015 2:08 AM, Iain Buclaw via Digitalmars-d wrote:Writing the druntime end of things, which is really providing just two functions: d_throw (d_dwarf_throw to distinguish it) and the libunwind personality function: __dmd_personality_v0. The tricky part with the personality function will likely be recognizing std::exception* exceptions. I wonder if forwarding the call to __gxx_personality_v0 will work. I'll have to check, but I'm pretty certain that libunwind will call the C++ personality for you if you return `nothing found` from D personality function.Why should it? What tells libunwind to call the C++ personality function? The generated EH tables only say call the D personality function.
Nov 12 2015
On Thursday, 12 November 2015 at 10:09:10 UTC, Iain Buclaw wrote:On 12 November 2015 at 07:50, Walter Bright via Digitalmars-d < digitalmars-d puremagic.com> wrote:The personality function is in the landingpad metadata. Why would libunwind call the C++ one out of nowhere ?I really appreciate the offers, and here's what will really help: Writing the druntime end of things, which is really providing just two functions: d_throw (d_dwarf_throw to distinguish it) and the libunwind personality function: __dmd_personality_v0. The tricky part with the personality function will likely be recognizing std::exception* exceptions. I wonder if forwarding the call to __gxx_personality_v0 will work.I'll have to check, but I'm pretty certain that libunwind will call the C++ personality for you if you return `nothing found` from D personality function.
Nov 12 2015
On 12 November 2015 at 11:17, deadalnix via Digitalmars-d < digitalmars-d puremagic.com> wrote:On Thursday, 12 November 2015 at 10:09:10 UTC, Iain Buclaw wrote:I did say that I'd have to check. :-) In any case, I'm doubtful that forwarding to C++'s personality would work.On 12 November 2015 at 07:50, Walter Bright via Digitalmars-d < digitalmars-d puremagic.com> wrote:The personality function is in the landingpad metadata. Why would libunwind call the C++ one out of nowhere ?I really appreciate the offers, and here's what will really help: Writing the druntime end of things, which is really providing just two functions: d_throw (d_dwarf_throw to distinguish it) and the libunwind personality function: __dmd_personality_v0. The tricky part with the personality function will likely be recognizing std::exception* exceptions. I wonder if forwarding the call to __gxx_personality_v0 will work. I'll have to check, but I'm pretty certain that libunwind will call theC++ personality for you if you return `nothing found` from D personality function.
Nov 12 2015
On 2015-11-12 11:37, Iain Buclaw via Digitalmars-d wrote:In any case, I'm doubtful that forwarding to C++'s personality would work.Objective-C does that [1]. [1] http://www.opensource.apple.com/source/objc4/objc4-647/runti e/objc-exception.mm search for "__objc_personality_v0" -- /Jacob Carlborg
Nov 12 2015
On Thursday, 12 November 2015 at 10:56:01 UTC, Jacob Carlborg wrote:On 2015-11-12 11:37, Iain Buclaw via Digitalmars-d wrote:ObjC doesn't do cleanup, so that's a bit different.In any case, I'm doubtful that forwarding to C++'s personality would work.Objective-C does that [1]. [1] http://www.opensource.apple.com/source/objc4/objc4-647/runti e/objc-exception.mm search for "__objc_personality_v0"
Nov 12 2015
On Thursday, 12 November 2015 at 06:50:31 UTC, Walter Bright wrote:In order to interoperate with modern C++, it has been abundantly clear for some time that D needs some support for C++ exception handling: 1. Have D finally blocks executed in D code that sits between a C++ try and catch 2. Have C++ finally blocks executed in C++ code that sits between a D try and catch 3. Be able to catch in D code an std::exception* or a C++ class derived from that. 4. Throw an std::exception* from D code. That's the minimum credible support, and is likely all D will actually need.I also started working on C++ exception handling for LDC/Calypso, I almost caught my first std::exception yesterday! (it went into the right catch and the IR looks right but _cxa_begin_catch() seems to return null instead of the exception object for some reason) Clang and Calypso made the std::type_info stuff a breeze, getting the type_info value for any C++ type was one line of code. I'll push the changes as is into a branch tonight, it's about ~400 lines.The tricky part with the personality function will likely be recognizing std::exception* exceptions. I wonder if forwarding the call to __gxx_personality_v0 will work.From what I gathered even if you manage to make the format of the LSDA tables compatible with __gxx_personality_v0, one blocker is that it still expects std::type_info pointers in the action table so will choke if it encounters D's TypeInfo_Class in there. To check if a type_info from a catch clause handles the thrown exception it calls the virtual method type_info::__do_catch (which is what Calypso does too) so can't work with D classes.
Nov 12 2015
On Thursday, 12 November 2015 at 06:50:31 UTC, Walter Bright wrote:The tricky part with the personality function will likely be recognizing std::exception* exceptions. I wonder if forwarding the call to __gxx_personality_v0 will work.This should be rather simple; you know it is C++ because of the metadata, and if you have access to RTTI (can just be hacked together with pragma(mangle, …)), you just do the type comparison then. What has me quite a bit more worried is the lifetime handling involved in the usual "throw std::exception subclass by value, catch base class by reference" idiom. If I remember correctly, both GCC and Clang handle this by injecting a runtime function call into the end of the catch blocks. Their implementation must also support keeping the value around for rethrowing. At this point, I'm not aware of any fundamental incompatibilities, but it will certainly add to the complexity of the solution. — David
Nov 12 2015
Sorry for the delay, here's the initial commit for C++ exception catching in Calypso: https://github.com/Syniurge/Calypso/commit/8b55ec1f013c29df86455ab055fbba91a72d92af https://github.com/Syniurge/druntime/commit/d33d8bf32c739bf9a30705dfc764718c817f16b1 The main files of interest are: https://github.com/Syniurge/druntime/blob/release-0.16.1/src/ldc/eh/cpp/gnu.d https://github.com/Syniurge/Calypso/blob/master/gen/cpp/cppeh.cpp And a basic example which segfaults at e.what() because __cxa_begin_catch returns null: https://github.com/Syniurge/Calypso/blob/master/tests/calypso/eh/std_exception.d Resulting IR : https://paste.kde.org/pvi2bokqx catch (C++) were added to be able to catch any type, and that's the only cost for being able to catch any C++ exception and not just std::exception I think, Clang and the libstdc++ makes working with std::type_info very easy. For the time the handler uses unwind-cxx.h copied from GNU's libstdc++ (it's an internal header which doesn't ship with any Ubuntu package). Its license is more permissive than the GPL, but if it isn't compatible it could be replaced by its libc++ equivalent.
Nov 14 2015