Any libunwind experts n da house?

IgorStepanov via Digitalmars-d digitalmars-d at puremagic.com
Sun Sep 28 14:22:25 PDT 2014


On Saturday, 27 September 2014 at 23:31:17 UTC, Andrei 
Alexandrescu wrote:
> On 9/27/14, 1:31 PM, IgorStepanov wrote:
>> 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.
>
> If that's what's needed, definitely please do explore it! But I 
> defer expertise to Walter. -- 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)?


More information about the Digitalmars-d mailing list