Jump to page: 1 2 3
Thread overview
Catching C++ std::exception in D
Nov 12, 2015
Walter Bright
Nov 12, 2015
krzaq
Nov 12, 2015
Kagamin
Nov 12, 2015
krzaq
Nov 12, 2015
Iain Buclaw
Nov 12, 2015
Walter Bright
Nov 12, 2015
Iain Buclaw
Nov 12, 2015
Johannes Pfau
Nov 12, 2015
Dan Olson
Nov 13, 2015
Johannes Pfau
Nov 13, 2015
Dan Olson
Nov 13, 2015
Iain Buclaw
Nov 14, 2015
David Nadlinger
Nov 15, 2015
Dan Olson
Nov 14, 2015
Dan Olson
Nov 12, 2015
David Nadlinger
Nov 12, 2015
Jacob Carlborg
Nov 12, 2015
Iain Buclaw
Nov 12, 2015
Walter Bright
Nov 12, 2015
Jacob Carlborg
Nov 12, 2015
Iain Buclaw
Nov 12, 2015
Walter Bright
Nov 12, 2015
deadalnix
Nov 12, 2015
Iain Buclaw
Nov 12, 2015
Jacob Carlborg
Nov 12, 2015
deadalnix
Nov 12, 2015
Elie Morisse
Nov 12, 2015
David Nadlinger
Nov 15, 2015
Elie Morisse
November 12, 2015
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.
November 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:
>
> [...]

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.
November 12, 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.
November 12, 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:
>> 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.

Sure, but it's idiomatic to catch by reference, hence the question.
November 12, 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


November 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
November 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 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
>


C++ 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
Iain


November 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.

November 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.

November 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.


« First   ‹ Prev
1 2 3