-
Notifications
You must be signed in to change notification settings - Fork 19
add test for catching D exceptions from C++ on Win32 #15
base: ldc
Are you sure you want to change the base?
Conversation
Very cool to see this working already! |
virtual void _classinfo_data() = 0; | ||
|
||
protected: | ||
// don't call directly, ABI mismatch |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you elaborate a bit on the ABI mismatch? I assumed ABI compliance between D and C++ would already be checked by dmd-testsuite...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this just duplicating the normal – extern(D)! – class definition in C++ and hoping that it somehow works?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand rainers/druntime@9dce356 correctly, it allows you to catch a D exception in C++ by declaring a C++ type with the same class name as the native D exception in a D
namespace (convention © Rainer ;)). That's why each thrown exception's type incl. base types are 'mangled' twice. Note that MSVC EH is based on strings specifying an exception's types (incl. base types).
The definition of the C++ type doesn't really matter, as long as the exception object isn't accessed; Rainer's test only uses toString()
, for which he wrote a specific C++ implementation anyway (calling back into druntime, apparently due to ABI mismatches). By duplicating the D class definitions of Object
, Throwable
etc. I guess he wanted to pave the way for a catch-D-exceptions lib for C++.
As soon as clang supports extern "D"
name mangling, we don't need this additional mangling for MSVC++ anymore. :D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that's what I gathered too – but what's way worse than the different mangling are the differences in object layout. I suppose you could manually "decode" and call the vtable entries on the C++ side, though, for a proper solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant this test as a show case how easy it is now to mix exception handling between D and C++. Catching C++ exception in D needs a few changes to the front end (allowing C++ classes as catch type) that Walter added only very recently, so I guess it'll need some time until this is in LDC. Mirroring the D definitions with a C++ definition is just the same as declaring a C++ class in D.
Unfortunately, Walter chose a different ABI than the C++ compiler for x86 (http://dlang.org/spec/abi.html), especially this
is passed in EAX, not ECX as for __thiscall
. That's why mapping virtual functions doesn't work without making the class extern(C++) in D. I don't think this should be done to the D exceptions.
The actual virtual functions are just for documentation here, just exposing the useful wrappers should be ok, too.
Writing the binding function _d_toString
on the D side has the big advantage that D knows both sides of the ABI, so you don't have to dig into assembly. It could be generalized to call any virtual function by specifying the offset in the vtbl, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extern(D)!
Yeah, stupid me, completely forgot about that for a moment. The fever I had the last few days must have damaged my brain...
Do you think this alternative C++ mangling + _d_toString
should be merged into druntime as-is? Or is it meant as prototype for a standardized upstream approach?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think this alternative C++ mangling + _d_toString should be merged into druntime as-is? Or is it meant as prototype for a standardized upstream approach?
I'm not sure. This possibility is currently very specific to the WinEH implementation, I doubt it is feasible in dmd. I don't know if something similar would be possible for other platforms.
7cf0d4b
to
a99e368
Compare
This takes advantage of recent changes to ldc-developers/druntime#54