Skip to content
This repository has been archived by the owner on Feb 8, 2024. It is now read-only.

add test for catching D exceptions from C++ on Win32 #15

Open
wants to merge 1 commit into
base: ldc
Choose a base branch
from

Conversation

rainers
Copy link
Contributor

@rainers rainers commented Jan 29, 2016

This takes advantage of recent changes to ldc-developers/druntime#54

@kinke
Copy link
Member

kinke commented Jan 30, 2016

Very cool to see this working already!

virtual void _classinfo_data() = 0;

protected:
// don't call directly, ABI mismatch
Copy link
Member

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

Copy link
Member

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?

Copy link
Member

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

Copy link
Member

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.

Copy link
Contributor Author

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.

Copy link
Member

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?

Copy link
Contributor Author

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.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants