September 27, 2014
On Saturday, 27 September 2014 at 20:18:42 UTC, Andrei Alexandrescu wrote:
> On 9/27/14, 12:53 PM, IgorStepanov wrote:
>> On Saturday, 27 September 2014 at 18:33:24 UTC, Jacob Carlborg wrote:
>>> On Saturday, 27 September 2014 at 11:34:32 UTC, IgorStepanov wrote:
>>>
>>>> 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).
>>>
>>> Objective-C can do it somehow. If they can do it I'm sure we can as well.
>>>
>>> --
>>> /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.
>
> Would that be for throwing exceptions from D into C++? I think we can postpone that for now. -- 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.
September 27, 2014
On Saturday, 27 September 2014 at 20:11:34 UTC, Iain Buclaw via Digitalmars-d wrote:
> On 27 September 2014 10:53, Jacob Carlborg via Digitalmars-d
> <digitalmars-d@puremagic.com> wrote:
>> On 2014-09-23 19:37, Andrei Alexandrescu wrote:
>>>
>>> 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.
>>
>
> 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?
September 27, 2014
On 27 Sep 2014 21:35, "IgorStepanov via Digitalmars-d" < digitalmars-d@puremagic.com> wrote:
>
> On Saturday, 27 September 2014 at 20:11:34 UTC, Iain Buclaw via
Digitalmars-d wrote:
>>
>> On 27 September 2014 10:53, Jacob Carlborg via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>>>
>>> On 2014-09-23 19:37, Andrei Alexandrescu wrote:
>>>>
>>>>
>>>> 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.
>>>
>>
>> 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.


September 27, 2014
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
September 28, 2014
On 2014-09-27 21:53, IgorStepanov wrote:

> 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
September 28, 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)?
1 2 3 4 5 6
Next ›   Last »