Discussion:
Any libunwind experts n da house?
Andrei Alexandrescu via Digitalmars-d
10 years ago
Permalink
We need a libunwind expert to figure out a good approach for handling
exceptions thrown by C++ code into D.

Is anyone fluent with libunwind?


Andrei
David Nadlinger via Digitalmars-d
10 years ago
Permalink
On Tuesday, 23 September 2014 at 17:37:42 UTC, Andrei
Post by Andrei Alexandrescu via Digitalmars-d
We need a libunwind expert to figure out a good approach for
handling exceptions thrown by C++ code into D.
Is anyone fluent with libunwind?
More or less.

What exactly are your goals? I thought the options we have are
fairly clear, as discussed a few days ago. At least, Amaury and I
seemed to agree (both of us worked on EH recently). The main
question to decide is whether you want to go down the
catch-C++-exceptions-in-D rabbit hole.

David
David Nadlinger via Digitalmars-d
10 years ago
Permalink
On Tuesday, 23 September 2014 at 18:03:18 UTC, David Nadlinger
Post by David Nadlinger via Digitalmars-d
On Tuesday, 23 September 2014 at 17:37:42 UTC, Andrei
Post by Andrei Alexandrescu via Digitalmars-d
We need a libunwind expert to figure out a good approach for
handling exceptions thrown by C++ code into D.
Is anyone fluent with libunwind?
[
]
The main question to decide is whether you want to go
down the catch-C++-exceptions-in-D rabbit hole.
Let me also note that if you do, it's no longer a question of
just libunwind, but also of C++ runtime internals. I assume your
primary target is g++ on Linux x86/x86_64?

David
Andrei Alexandrescu via Digitalmars-d
10 years ago
Permalink
Post by David Nadlinger via Digitalmars-d
Post by Andrei Alexandrescu via Digitalmars-d
We need a libunwind expert to figure out a good approach for handling
exceptions thrown by C++ code into D.
Is anyone fluent with libunwind?
[
]
The main question to decide is whether you want to go
down the catch-C++-exceptions-in-D rabbit hole.
Let me also note that if you do, it's no longer a question of just
libunwind, but also of C++ runtime internals. I assume your primary
target is g++ on Linux x86/x86_64?
Yes. -- Andrei
Andrei Alexandrescu via Digitalmars-d
10 years ago
Permalink
...
I think we should explore that rabbit hole. In the interim, a simpler
solution may work: a C++ exception can only be caught from within C++
code. If no handler, the program terminates reliably. -- Andrei
deadalnix via Digitalmars-d
10 years ago
Permalink
On Tuesday, 23 September 2014 at 18:14:35 UTC, Andrei
...
Here is the other side of the rabbit hole you want to be
compatible with: libstdc++-v3//libsupc++/eh_personality.cc (from
GCC source tree, svn checkout svn://gcc.gnu.org/svn/gcc/trunk
SomeLocalDir ).

I think catching C++ exception may be realistic on the long run,
but having them unwind properly should probably be the goal on
the short run.
Walter Bright via Digitalmars-d
10 years ago
Permalink
...
One goal is to have dmd use the g++ exception handling mechanism. But googling
how that works, I find dead links, specs that are 15 years old accompanied by
vague comments about it being "extended" and "look at the g++ source code", etc.

Are there any actual docs about how it works for x86? Or is it the usual "take
apart the output of g++ and figure it out" that I usually wind up doing :-( ?
Jason King via Digitalmars-d
10 years ago
Permalink
I believe pretty much anything *ix on 64-bit(at least) x86 (32-bit gets a
bit murkier due to historical issues) is using the same exception handling
ABI (which itself was based off the Itanic ABI):

http://www.x86-64.org/documentation/abi.pdf



On Tue, Sep 23, 2014 at 1:31 PM, Walter Bright via Digitalmars-d <
...
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20140923/d0ddb18d/attachment.html>
Walter Bright via Digitalmars-d
10 years ago
Permalink
I believe pretty much anything *ix on 64-bit(at least) x86 (32-bit gets a bit
murkier due to historical issues) is using the same exception handling ABI
http://www.x86-64.org/documentation/abi.pdf
Thanks, this contains part of the info.
Jacob Carlborg via Digitalmars-d
10 years ago
Permalink
Post by Walter Bright via Digitalmars-d
One goal is to have dmd use the g++ exception handling mechanism.
That would be cool. It's useful for Objective-C on x86-64 as well.
Post by Walter Bright via Digitalmars-d
But googling how that works, I find dead links, specs that are 15 years old
accompanied by vague comments about it being "extended" and "look at the
g++ source code", etc.
Are there any actual docs about how it works for x86? Or is it the usual
"take apart the output of g++ and figure it out" that I usually wind up
doing :-( ?
From the LLVM docs [1]:

A more complete description of the Itanium ABI exception handling
runtime support of can be found at Itanium C++ ABI: Exception Handling
[2]. A description of the exception frame format can be found at
Exception Frames [3], with details of the DWARF 4 specification at DWARF
4 Standard [4]. A description for the C++ exception table formats can be
found at Exception Handling Tables [5].

[1]
http://llvm.org/docs/ExceptionHandling.html#itanium-abi-zero-cost-exception-handling

[2] http://mentorembedded.github.com/cxx-abi/abi-eh.html

[3]
http://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html

[4] http://dwarfstd.org/Dwarf4Std.php

[5] http://mentorembedded.github.com/cxx-abi/exceptions.pdf
--
/Jacob Carlborg
Walter Bright via Digitalmars-d
10 years ago
Permalink
Thank you. This is helpful.
David Nadlinger via Digitalmars-d
10 years ago
Permalink
On Tuesday, 23 September 2014 at 20:29:22 UTC, Walter Bright
Post by Walter Bright via Digitalmars-d
Thank you. This is helpful.
Yes, that's quite a nice list already.

As far as the C++ implementation details go, I posted the most
interesting source files in the earlier discussion:
http://forum.dlang.org/thread/lutf3c$2usj$1 at digitalmars.com (the
GCC ones can be found in the GCC release tarballs, the OS X Clang
ones at http://llvm.org/svn/llvm-project/libcxxabi/trunk/src/).

David
Andrei Alexandrescu via Digitalmars-d
10 years ago
Permalink
Post by David Nadlinger via Digitalmars-d
Post by Walter Bright via Digitalmars-d
Thank you. This is helpful.
Yes, that's quite a nice list already.
As far as the C++ implementation details go, I posted the most
http://forum.dlang.org/thread/lutf3c$2usj$1 at digitalmars.com (the GCC
ones can be found in the GCC release tarballs, the OS X Clang ones at
http://llvm.org/svn/llvm-project/libcxxabi/trunk/src/).
David
Speaking of which, what's the current story with gdc and ldc with regard
to unwinding? Can they unwind properly when a C++ exception gets thrown?
-- Andrei
David Nadlinger via Digitalmars-d
10 years ago
Permalink
On Tuesday, 23 September 2014 at 21:20:37 UTC, Andrei
Post by Andrei Alexandrescu via Digitalmars-d
Speaking of which, what's the current story with gdc and ldc
with regard to unwinding? Can they unwind properly when a C++
exception gets thrown? -- Andrei
Currently, the LDC runtime just aborts, but that wouldn't be too
hard to fix.

David
Iain Buclaw via Digitalmars-d
10 years ago
Permalink
On 23 September 2014 22:20, Andrei Alexandrescu via Digitalmars-d
...
GDC lets foreign exceptions pass through just fine. The only time
when runtime terminates is when GDC has no choice *but* to handle a
foreign exception it doesn't know about.


By all means, you can have this kind of code:
---
D:
extern(C++) int Dfunction()
{
try {
return CXXfunction(2);
}
catch {
return 8;
}
}
---
C++:
int main() {
try {
return Dfunction();
}
catch (int error) {
return error;
}
}

int CXXfunction(int i)
{
throw int(16);
return i * 2;
}

And the runtime flow is:
Phase 1.
=> __gdc_personality_v0 // Found nothing, continue unwinding.
=> __gxx_personality_v0 // Found something, cache details and continue unwind

Phase 2.
=> __gdc_personality_v0 // Found nothing, continue unwinding.
=> __gxx_personality_v0 // Found something, finish unwinding.

And we land back in C++ main, return 16.

Iain.
Andrei Alexandrescu via Digitalmars-d
10 years ago
Permalink
Post by Iain Buclaw via Digitalmars-d
GDC lets foreign exceptions pass through just fine.
Proper unwinding of the D stack and all? -- Andrei
Iain Buclaw via Digitalmars-d
10 years ago
Permalink
On 23 September 2014 23:44, Andrei Alexandrescu via Digitalmars-d
Post by Andrei Alexandrescu via Digitalmars-d
Post by Iain Buclaw via Digitalmars-d
GDC lets foreign exceptions pass through just fine.
Proper unwinding of the D stack and all? -- Andrei
If you mean in the sense that libunwind will happily work it's way up,
bouncing between D / C++ stacks until it finds a catch handler, then
yes.

Otherwise, please give an example.

Iain
Andrei Alexandrescu via Digitalmars-d
10 years ago
Permalink
Post by Iain Buclaw via Digitalmars-d
On 23 September 2014 23:44, Andrei Alexandrescu via Digitalmars-d
Post by Andrei Alexandrescu via Digitalmars-d
Post by Iain Buclaw via Digitalmars-d
GDC lets foreign exceptions pass through just fine.
Proper unwinding of the D stack and all? -- Andrei
If you mean in the sense that libunwind will happily work it's way up,
bouncing between D / C++ stacks until it finds a catch handler, then
yes.
Yah, that's what I meant. Thanks! -- Andrei
deadalnix via Digitalmars-d
10 years ago
Permalink
On Tuesday, 23 September 2014 at 17:37:42 UTC, Andrei
Post by Andrei Alexandrescu via Digitalmars-d
We need a libunwind expert to figure out a good approach for
handling exceptions thrown by C++ code into D.
Is anyone fluent with libunwind?
Andrei
https://github.com/deadalnix/libsdrt/blob/master/src/d/rt/eh.d
Iain Buclaw via Digitalmars-d
10 years ago
Permalink
On 23 September 2014 22:29, deadalnix via Digitalmars-d
Post by David Nadlinger via Digitalmars-d
On Tuesday, 23 September 2014 at 17:37:42 UTC, Andrei
Post by Andrei Alexandrescu via Digitalmars-d
We need a libunwind expert to figure out a good approach for handling
exceptions thrown by C++ code into D.
Is anyone fluent with libunwind?
Andrei
https://github.com/deadalnix/libsdrt/blob/master/src/d/rt/eh.d
https://github.com/D-Programming-GDC/GDC/blob/master/libphobos/libdruntime/gcc/deh.d

:o)
Andrei Alexandrescu via Digitalmars-d
10 years ago
Permalink
...
Noice. How difficult would be to port this to dmd/Linux? This is big -
we need to get it done, and soon.

Andrei
Walter Bright via Digitalmars-d
10 years ago
Permalink
...
There is a problem, that code is gpl licensed. It may not actually matter, since
this code is only to interface with gpl libraries, but we should be careful.
Iain Buclaw via Digitalmars-d
10 years ago
Permalink
On 23 September 2014 23:56, Walter Bright via Digitalmars-d
...
As well as the license, there's also two technical details that need
to be addressed to fit with the features of dmd EH.

1) Exception chaining - still on my todo
2) OOM exceptions could be handled better.

By all means, I'm happy with you to use it as a point of reference.

What you'll find is that pretty much all GCC frontend personality
routines are essentially identical, barring the of handling it's own
exception object / data.

Iain.
IgorStepanov via Digitalmars-d
10 years ago
Permalink
On Tuesday, 23 September 2014 at 17:37:42 UTC, Andrei
Post by Andrei Alexandrescu via Digitalmars-d
We need a libunwind expert to figure out a good approach for
handling exceptions thrown by C++ code into D.
Is anyone fluent with libunwind?
Andrei
Is there plans to catching C++ exceptions in D?
What kind of C++ exceptions planned to catch in D?
For example C++ can throw primitive types exceptions, for example
int.
Of cource, them can be wrapped into special D CPPException :
Throwable, class, which contains string representation of C++
exception.
What about C++ polymorthic exceptions? AFAIK, C++ exception are
throwing by-value, and catching by ref (to allow polimorthic
catch). Where C++ calls destructor for exception? In catch block?
In D GC handles an exception lifetime.
Is there any ideas about it?
P.S. I tell about user-side of catching C++ exceptions, not about
implementation.
Iain Buclaw via Digitalmars-d
10 years ago
Permalink
On 24 September 2014 12:27, IgorStepanov via Digitalmars-d
Post by IgorStepanov via Digitalmars-d
Post by Andrei Alexandrescu via Digitalmars-d
We need a libunwind expert to figure out a good approach for handling
exceptions thrown by C++ code into D.
Is anyone fluent with libunwind?
Andrei
Is there plans to catching C++ exceptions in D?
I'd say no to such an idea.
Post by IgorStepanov via Digitalmars-d
What kind of C++ exceptions planned to catch in D?
None
...
Let C++ land catch the exception and deal with it.

Iain.
Andrei Alexandrescu via Digitalmars-d
10 years ago
Permalink
Post by Iain Buclaw via Digitalmars-d
On 24 September 2014 12:27, IgorStepanov via Digitalmars-d
Post by IgorStepanov via Digitalmars-d
Post by Andrei Alexandrescu via Digitalmars-d
We need a libunwind expert to figure out a good approach for handling
exceptions thrown by C++ code into D.
Is anyone fluent with libunwind?
Andrei
Is there plans to catching C++ exceptions in D?
I'd say no to such an idea.
I understand the difficulty of it. However, we should look into it
closely. Preventing D code from catching C++ exceptions forces one to
implement the driver/event loop/etc in C++, which is quite unpleasant.
It essentially takes C++ compatibility a few good notches down.
Post by Iain Buclaw via Digitalmars-d
Post by IgorStepanov via Digitalmars-d
What kind of C++ exceptions planned to catch in D?
None
I wonder how difficult would be to create a wrapper class CppException
for everything derived from C++ std::exception. It would not save the
exact exception, but it would save its what() string and perhaps the
typeid().name(). A translator would create CppException objects from
std::exception objects and their derivatives.

How hard would that be? Please advise.
...
Believe me, I hear you :o). I'm afraid we need to do something better
about it.


Andrei
Sean Kelly via Digitalmars-d
10 years ago
Permalink
On Wednesday, 24 September 2014 at 15:07:05 UTC, Andrei
Post by Andrei Alexandrescu via Digitalmars-d
Post by Iain Buclaw via Digitalmars-d
Post by IgorStepanov via Digitalmars-d
Is there plans to catching C++ exceptions in D?
I'd say no to such an idea.
I understand the difficulty of it. However, we should look into
it closely. Preventing D code from catching C++ exceptions
forces one to implement the driver/event loop/etc in C++, which
is quite unpleasant. It essentially takes C++ compatibility a
few good notches down.
If C++ code can execute D delegates, perhaps an intermediate step
would be to create a wrapper in C++ that calls the delegate
wrapped in an appropriate try/catch block. Syntax would be a bit
weird as you'd have to specify a callback for each exception type
you wanted to catch, but it seems doable.
Andrei Alexandrescu via Digitalmars-d
10 years ago
Permalink
...
That's a good idea, thanks. -- Andrei
Iain Buclaw via Digitalmars-d
10 years ago
Permalink
On 24 September 2014 16:07, Andrei Alexandrescu via Digitalmars-d
...
Thinking about it:

- Identifying a C++ exception, simple.

- Identifying whether a D catch handler for a C++ exception object
matches, tricky - maybe. ABI of structs being a potential maintenance
burden - though you'd hope that they only change ABI once every two
years or so. Second, determining that the C++ object being thrown and
catch handler we are examining match might be awkward from D. That is
something that needs investigation.

However, for sure, the easiest thing that could be done *now* that
only needs a slight EH library tweak is using catch-all handlers to
recover from any language exception.

try {
SomeCxxFuncThatMayThrow();
}
catch {
// Recover, but without knowing what happened.
}

But I'd imagine you'd actually want information to come with your
caught exception, though. :)

Iain
Andrei Alexandrescu via Digitalmars-d
10 years ago
Permalink
Post by Iain Buclaw via Digitalmars-d
On 24 September 2014 16:07, Andrei Alexandrescu via Digitalmars-d
I wonder how difficult would be to create a wrapper class CppException for
everything derived from C++ std::exception. It would not save the exact
exception, but it would save its what() string and perhaps the
typeid().name(). A translator would create CppException objects from
std::exception objects and their derivatives.
How hard would that be? Please advise.
- Identifying a C++ exception, simple.
Noice.
Post by Iain Buclaw via Digitalmars-d
- Identifying whether a D catch handler for a C++ exception object
matches, tricky - maybe. ABI of structs being a potential maintenance
burden - though you'd hope that they only change ABI once every two
years or so. Second, determining that the C++ object being thrown and
catch handler we are examining match might be awkward from D. That is
something that needs investigation.
Yah. I'm thinking of simplifying assumptions, e.g. all C++ exceptions
map to one single D type called CppException, and we can assume there's
always a D handler on top of the stack. All the CppException saves is a
copy of the what() message from the C++ exception.
Post by Iain Buclaw via Digitalmars-d
However, for sure, the easiest thing that could be done *now* that
only needs a slight EH library tweak is using catch-all handlers to
recover from any language exception.
try {
SomeCxxFuncThatMayThrow();
}
catch {
// Recover, but without knowing what happened.
}
But I'd imagine you'd actually want information to come with your
caught exception, though. :)
Well even a catch like that would definitely be an improvement.


Andrei
deadalnix via Digitalmars-d
10 years ago
Permalink
On Wednesday, 24 September 2014 at 19:28:50 UTC, Andrei
Post by Andrei Alexandrescu via Digitalmars-d
Post by Iain Buclaw via Digitalmars-d
However, for sure, the easiest thing that could be done *now*
that
only needs a slight EH library tweak is using catch-all
handlers to
recover from any language exception.
try {
SomeCxxFuncThatMayThrow();
}
catch {
// Recover, but without knowing what happened.
}
But I'd imagine you'd actually want information to come with
your
caught exception, though. :)
Well even a catch like that would definitely be an improvement.
Considered it for SDC. it is not that simple as if it is a C++
exception, you need to do the same cleanup of the exception that
the C++ runtime would do, which is not that simple.
Iain Buclaw via Digitalmars-d
10 years ago
Permalink
On 24 September 2014 21:11, deadalnix via Digitalmars-d
...
Hmm... I forgot about the C++ compiler emitting function calls for the
begin/end of catches. Yeah, that would indeed need to be supported on
the compiler side!
IgorStepanov via Digitalmars-d
10 years ago
Permalink
On Wednesday, 24 September 2014 at 19:28:50 UTC, Andrei
...
I have one freaky example for you. This example can be
non-standart and danger but it works:
C++ side: http://pastebin.ru/PceYCOEq
special function catch exception, pass it to specified handler
and re-throw, if handler not found

D side: http://pastebin.ru/7FNBzXHw
D defines a special handler and pass it to catchException
result:
D code call C++ function

void throwEx(void *)
{
throw 4;
}
and prints:
dside.CPPException!int.CPPException@(0): 4

Doesn't fire to me, please :)
IgorStepanov via Digitalmars-d
10 years ago
Permalink
Now DMD doesn't support thorowing C++ exceptions through D
function:

extern(C++)
void throwEx(); //compiled by G++ and throws exception

extern(C++)
void dFunc(void*)
{
throwEx();
}


catchException(&dFunc, ...); //terminate programm instead of
catch it. Should be works in gdc
Andrei Alexandrescu via Digitalmars-d
10 years ago
Permalink
Post by IgorStepanov via Digitalmars-d
I have one freaky example for you. This example can be
C++ side: http://pastebin.ru/PceYCOEq
special function catch exception, pass it to specified handler
and re-throw, if handler not found
D side: http://pastebin.ru/7FNBzXHw
D defines a special handler and pass it to catchException
D code call C++ function
void throwEx(void *)
{
throw 4;
}
Doesn't fire to me, please :)
Awesome! How do we make it standard and safe? -- Andrei
IgorStepanov via Digitalmars-d
10 years ago
Permalink
On Wednesday, 24 September 2014 at 22:14:5 UTC, Andrei
...
C++ hasn't standart abi(
If we talk about g++, this code has a one conspicuous trouble: I
don't know, how to correctly get a pointer to exception. Class
exception_ptr has getter for it, but it is private. I'll think
about another variants.
And I don't know about <cxxabi.h> standartness.
The second trouble: if we want to do something more exception
printing, we should get an exception pointer to user. However,
user shouldn't copy this pointer, because exception object will
be destroyed in cpp side.
Good news: this code (D side) can be generated by D compiler:
try
{
// C++ exceptions danger
}
catch(CPPException!int e)
{
}
catch(CPPException!myException e)
{
}

Of course, only exact match of exception will be works. No
polymorphism.
Kagamin via Digitalmars-d
10 years ago
Permalink
On Wednesday, 24 September 2014 at 15:07:05 UTC, Andrei
Post by Andrei Alexandrescu via Digitalmars-d
I wonder how difficult would be to create a wrapper class
CppException for everything derived from C++ std::exception.
Why not catch std::exception directly? Then you could generate
code, just like C++ compiler does it.
Andrei Alexandrescu via Digitalmars-d
10 years ago
Permalink
Post by Andrei Alexandrescu via Digitalmars-d
I wonder how difficult would be to create a wrapper class CppException
for everything derived from C++ std::exception.
Why not catch std::exception directly? Then you could generate code,
just like C++ compiler does it.
That would be a language change - right now D can only catch Exception
objects.

Andrei
Kagamin via Digitalmars-d
10 years ago
Permalink
On Thursday, 25 September 2014 at 13:58:23 UTC, Andrei
Post by Andrei Alexandrescu via Digitalmars-d
That would be a language change - right now D can only catch
Exception objects.
Isn't the idea to let D do more things with C++ things?
Kagamin via Digitalmars-d
10 years ago
Permalink
I mean, D's inability to interoperate with C++ is not a feature,
but a problem meant to be solved as long as it doesn't take too
much effort.
IgorStepanov via Digitalmars-d
10 years ago
Permalink
On Thursday, 25 September 2014 at 13:58:23 UTC, Andrei
Post by Andrei Alexandrescu via Digitalmars-d
Post by Sean Kelly via Digitalmars-d
On Wednesday, 24 September 2014 at 15:07:05 UTC, Andrei
Post by Andrei Alexandrescu via Digitalmars-d
I wonder how difficult would be to create a wrapper class
CppException
for everything derived from C++ std::exception.
Why not catch std::exception directly? Then you could generate code,
just like C++ compiler does it.
That would be a language change - right now D can only catch
Exception objects.
Andrei
I've implemented an experemental "framework" to catching C++
exceptions from D.
https://github.com/IgorStepanov/D-CPP-Exception-Handle
It works with G++, and depends on "unwind-cxx.h" header, which
has been stealed from "libstdc++/libsupc++/". libsupc++ is a part
of libstdc++ and this file can be found in libstdc++ sources.
However, libstdc++ developers doesn't publish this header and it
cannot be found in /usr/include/

This "framework" allows to call external C++ function and call
exception, if good handler is passed. Also it can process
polymorphic exceptions: in attached example I throws
std::logic_exception and catches std::exception:

//C++

#include <stdexcept>

//test function
void throwEx(void *)
{
throw std::logic_error("Catch me, if you can");
}

//D
extern(C++) void throwEx(void *);

void main()
{
/*
code like ...
try
{
throwEx(null);
}
catch(std.exception val)
{
printf("exception: '%s'\n", val.what());
}

may be rewritten as
*/

Try!(throwEx)(
(CPPException!int ex)
{
printf("exception: '%d'\n", *ex.data);
return 0;
},
(CPPException!(stdexceptions.std.exception) ex)
{
printf("exception: '%s'\n", ex.data.what());
return 0;
}
);
}
//prints: exception: 'Catch me, if you can'


However, DMD can't pass С++ exceptions through D function
(including extern(C++)). Thus, we cant pass delegate to Try
function instead of throwEx, but this trouble can be resolved, I
think.
deadalnix via Digitalmars-d
10 years ago
Permalink
Congrat, that is some awesome work. I will certainly dig into
this.
Jacob Carlborg via Digitalmars-d
10 years ago
Permalink
Post by Andrei Alexandrescu via Digitalmars-d
We need a libunwind expert to figure out a good approach for handling
exceptions thrown by C++ code into D.
BTW, are you only interested in handling C++ exception, or are you
interested in handling D exceptions in C++ as well?

One ugly hack is to register a terminate handler. Then in the handler
extract the necessary information from the exception, create a D
exception with this information and throw it as a regular D exception.

Throwing a D exception that should be catchable in C++ is a bit more
tricky. It's possible to wrap the a call to a D function in a try-catch
block. Convert the D exception to a C++ exception, then throw it using a
function part of the C++ exception runtime. The problem here is that C++
won't be able to catch this exception because there's no personality
function (or similar) setup by the D compiler.

Ideally D should just use the same exception mechanism as C++. I don't
think a language change is necessary for this. Changes in the compiler,
yes, but hopefully not in the language.
--
/Jacob Carlborg
IgorStepanov via Digitalmars-d
10 years ago
Permalink
On Saturday, 27 September 2014 at 09:53:37 UTC, Jacob Carlborg
Post by Jacob Carlborg via Digitalmars-d
Post by Andrei Alexandrescu via Digitalmars-d
We need a libunwind expert to figure out a good approach for
handling
exceptions thrown by C++ code into D.
BTW, are you only interested in handling C++ exception, or are
you interested in handling D exceptions in C++ as well?
Ideally D should just use the same exception mechanism as C++.
I don't think a language change is necessary for this. Changes
in the compiler, yes, but hopefully not in the language.
C++ exception mechanism uses C++ type_info objects. We can
inherit object.Throwable from std::exception (through extern(C++)
interface), override the what() method, but there are no way to
generate C++ type_info for D class now. If we want to do a
compiler support of C++ exceptions, we should implement and
support another one non-standartized feature: type_info. BTW it
allows to do dynamic_cast over C++ classes in D, but I think,
nobody approve this suggestion, because it can be hard).
Jacob Carlborg via Digitalmars-d
10 years ago
Permalink
On Saturday, 27 September 2014 at 11:34:32 UTC, IgorStepanov
Post by IgorStepanov via Digitalmars-d
C++ exception mechanism uses C++ type_info objects. We can
inherit object.Throwable from std::exception (through
extern(C++) interface), override the what() method, but there
are no way to generate C++ type_info for D class now. If we
want to do a compiler support of C++ exceptions, we should
type_info. BTW it allows to do dynamic_cast over C++ classes in
D, but I think, nobody approve this suggestion, because it can
be hard).
Objective-C can do it somehow. If they can do it I'm sure we can
as well.

--
/Jacob Carlborg
IgorStepanov via Digitalmars-d
10 years ago
Permalink
On Saturday, 27 September 2014 at 18:33:24 UTC, Jacob Carlborg
...
If someone from D commanders bless me, I can start to exploring
and implementing std::type_info for D classes. If we made it, we
will implement 50% of C++ exception handling.
Andrei Alexandrescu via Digitalmars-d
10 years ago
Permalink
...
Would that be for throwing exceptions from D into C++? I think we can
postpone that for now. -- Andrei
IgorStepanov via Digitalmars-d
10 years ago
Permalink
On Saturday, 27 September 2014 at 20:18:42 UTC, Andrei
...
No, that for throwing from C++ into D: for catch an exception, we
should pass type_info object to special C++ runtime function. C++
runtime determines, can throwed object type can be casted to
asked type, and if yes - allow catch it and do catcher code. If
you will see the my example, you will see that I do this
manually: get throwed type_info and compare its mangle with
requested mangle. If we will make it as possible, it will be work
better, faster and reliable. As bonus: possibility to implement
dynamic_cast over C++ classes.
Andrei Alexandrescu via Digitalmars-d
10 years ago
Permalink
No, that for throwing from C++ into D: for catch an exception, we should
pass type_info object to special C++ runtime function. C++ runtime
determines, can throwed object type can be casted to asked type, and if
yes - allow catch it and do catcher code. If you will see the my
example, you will see that I do this manually: get throwed type_info and
compare its mangle with requested mangle. If we will make it as
possibility to implement dynamic_cast over C++ classes.
If that's what's needed, definitely please do explore it! But I defer
expertise to Walter. -- Andrei
IgorStepanov via Digitalmars-d
10 years ago
Permalink
On Saturday, 27 September 2014 at 23:31:17 UTC, Andrei
...
Ok. Anyway, I can't work on this to the full extent, because I
have a three D works (six pull requests), which are waiting for
action from the D collaborators (UDA for modules PR reviewed and
is waiting for approval, multiple alias this and new AA
implementation are waiting for review).

However, I've seen this direction and I want to report a few
points:
1. C++ type_info/TypeHandle for classes is located on -1 index of
vtbl;
2. type_info layout aren't standartized (as expected) and differs
in G++, VS and (probably) DMC and SunC.
3. type_info in C++ uses in many different cases, like
dynamic_cast and excetion handling.
4. D doensn't generate type_info and it can cause danger
situation. e.g.

************************************
//C++ code
class CppBase
{
public:
virtual void test() = 0;
};

class CppDerived : public CppBase
{
public:
void test();
};


void CppDerived::test()
{
std::cout << "CppDerived::test()" << std::endl;
}

void doTest(CppBase *obj)
{
obj->test();
CppDerived *dobj = dynamic_cast<CppDerived *>(obj);
//Attention!
if (dobj)
{
std::cout << "casted" << std::endl;
}
else
{
std::cout << "fail" << std::endl;
}
}

//D code

extern(C++) interface CppBase
{
void test();
}


class DDerived : CppBase
{
extern(C++) override void test()
{
writeln("DDerived.test()");
}
}

extern(C++) void doTest(CppBase);

void main()
{
writeln("start test");
doTest(new DDerived()); //BOOM! segfault while processing
dynamic_cast, because DDerived type_info is wrong.
writeln("finish test");
}

************************************
//Now my suggestions:
1. We can implement type_info generation as library template like
GenTypeInfo(T). It will return valid type_info object for
supproted platforms and null for platforms, which isn't supported
yet.
2. Compiler will use this template to get type_info and push it
into vtbl (at -1 position)
3. In situation, when compile need to use type_info (may be
try-catch with C++ exceptions or dynamic_cast, it will be raise
error if type_info isn't implemented)

This approach allows to move complex, platform-depended code from
compiler to library. Also it allows to don't implement some
platforms without user restrictions.

In conclusion: this is a g++ type_info definitions:
https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/cxxabi.h#L535

This has a flag "__diamond_shaped_mask" in __vmi_class_type_info,
and "__virtual_mask" in __base_class_type_info.
D allows multiply inheritance for interfaces. In mapping to C++:
Is this inheritance virtual? Should we set __diamond_shaped_mask
is A: B, C; B : D; C : D (B, C, D is interfaces)?

Jacob Carlborg via Digitalmars-d
10 years ago
Permalink
If someone from D commanders bless me, I can start to exploring and
implementing std::type_info for D classes. If we made it, we will
implement 50% of C++ exception handling.
Objective-C seems to use a struct made of a vtable, the class name and
the Objective-C class as the type_info.
--
/Jacob Carlborg
Andrei Alexandrescu via Digitalmars-d
10 years ago
Permalink
Post by Jacob Carlborg via Digitalmars-d
Post by Andrei Alexandrescu via Digitalmars-d
We need a libunwind expert to figure out a good approach for handling
exceptions thrown by C++ code into D.
BTW, are you only interested in handling C++ exception, or are you
interested in handling D exceptions in C++ as well?
The more the merrier, but there's a large difference in importance. For
the most part D code (new) will call into C++ code (old) so it's the C++
exceptions we're most worried about. -- Andrei
IgorStepanov via Digitalmars-d
10 years ago
Permalink
On Saturday, 27 September 2014 at 19:16:24 UTC, Andrei
...
Can someone implement an C++ exception transparency? (when
exception, throwed from C++ can be passed through D function and
landed down in C++ code).
Then, if type_info is implemented, I will able to try to
implement C++ exception catching.
Iain Buclaw via Digitalmars-d
10 years ago
Permalink
On 27 September 2014 10:53, Jacob Carlborg via Digitalmars-d
...
Well, ObjC++ shares the same EH personality routines as C++, which
probably accounts for the compatibility. :)

Iain.
IgorStepanov via Digitalmars-d
10 years ago
Permalink
On Saturday, 27 September 2014 at 20:11:34 UTC, Iain Buclaw via
...
Is this way acceptable for D, or not. Why?
Iain Buclaw via Digitalmars-d
10 years ago
Permalink
On 27 Sep 2014 21:35, "IgorStepanov via Digitalmars-d" <
...
exception
Post by IgorStepanov via Digitalmars-d
Post by Iain Buclaw via Digitalmars-d
Post by Jacob Carlborg via Digitalmars-d
with this information and throw it as a regular D exception.
Throwing a D exception that should be catchable in C++ is a bit more
tricky.
Post by IgorStepanov via Digitalmars-d
Post by Iain Buclaw via Digitalmars-d
Post by Jacob Carlborg via Digitalmars-d
It's possible to wrap the a call to a D function in a try-catch block.
Convert the D exception to a C++ exception, then throw it using a
function
Post by IgorStepanov via Digitalmars-d
Post by Iain Buclaw via Digitalmars-d
Post by Jacob Carlborg via Digitalmars-d
part of the C++ exception runtime. The problem here is that C++ won't be
able to catch this exception because there's no personality function (or
similar) setup by the D compiler.
Ideally D should just use the same exception mechanism as C++. I don't
think
Post by IgorStepanov via Digitalmars-d
Post by Iain Buclaw via Digitalmars-d
Post by Jacob Carlborg via Digitalmars-d
a language change is necessary for this. Changes in the compiler, yes,
but
Post by IgorStepanov via Digitalmars-d
Post by Iain Buclaw via Digitalmars-d
Post by Jacob Carlborg via Digitalmars-d
hopefully not in the language.
Well, ObjC++ shares the same EH personality routines as C++, which
probably accounts for the compatibility. :)
Iain.
Is this way acceptable for D, or not. Why?
In the EH routines, we should be able to make do with a generic
CppException and pass it back to a D catch. What won't work too well is
catching a specific C++ exception.

Iain.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20140927/c776cf93/attachment.html>
Loading...