April 08, 2014 Re: Use C++ exception model in D | ||||
---|---|---|---|---|
| ||||
On 8 April 2014 21:06, Brad Roberts <braddr@puremagic.com> wrote:
> On 4/8/14, 12:56 PM, David Nadlinger wrote:
>>
>> On Tuesday, 8 April 2014 at 18:55:35 UTC, Brad Roberts wrote:
>>>
>>> I think, for a mixed language application, that the important part is
>>> proper object lifetime
>>> management more than being able to catch exceptions from different
>>> languages. When unwinding a
>>> c++ exception that has stack frames intermixed with D, destructors need
>>> to be executed
>>> appropriately, and vice versa.
>>
>>
>> I haven't actually tried to do this, but in theory, this should be the
>> easy part with libunwind. You
>> just ignore foreign exceptions during the search phase (i.e. not catch
>> them), and during the unwind
>> phase, your own personality function is called again for cleanup
>> regardless of the handler the stack
>> actually unwinds to.
>>
>>> This is also an important part of having abi compatibility between D
>>> compilers, something which we
>>> don't have today but really must have eventually.. hopefully not years
>>> away.
>>
>>
>> This really depends on somebody familiar with the DMD backend committing
>> to going through with it. I
>> think both on the GDC and LDC sides, there is agreement that we need to
>> work on a common ABI.
>> However, the whole thing would be somewhat of a futile effort without DMD
>> on board as well.
>>
>> On x86_64, ABI compatibility is not an unreasonable goal at all (and a
>> very important one, in my
>> opinion). There are some areas that will need a lot of careful spec'ing
>> and likely entail changes in
>> all three compilers, such as the construction of nested scopes. However,
>> in some cases, e.g.
>> exception unwinding, or proper variadic arguments, it's definitely the
>> case that GDC and LDC would
>> be easy to align, whereas DMD would have to give up its own bespoke
>> solution. Does DMD still do
>> things like magically accessing the scope of the parent function in in/out
>> contract calls?
>>
>> David
>
>
> Most of the areas where DMD is 'odd' are a case of "I can't figure out the right way, so any way is better than no way". That's particularly true for var args and eh. I'm confident that pulls that fix these issues can and will be accepted. I'm less confident that someone will volunteer to fix it, but it's something I care about.
Hopefully I've convinced Daniel to fix the va_args at least.
|
April 09, 2014 Re: Use C++ exception model in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Nadlinger | On 08/04/14 14:03, David Nadlinger wrote: > On Tuesday, 8 April 2014 at 10:08:24 UTC, Jacob Carlborg wrote: >> Is there a reason to not use the same model, or what's required to be >> compatible? > > In short, the reason not to use the same "model" (you could argue that > the model is the same, as only the personality functions differ) is that > the exception unwinder is intimately tied to both the target language > ABI and semantics. > > For example, all unwinders need to handle the run-time type information > for the exception object to correctly dispatch it. And while e.g. the > GNU C++ unwinding implementation needs to pull shenanigans to implement > the crazy C++ exception lifetime model (cf. catching by reference vs. by > value) and enforce throws(...) specifications, the D unwinder needs to > understand the difference between Exception and Error and correctly > implement exception chaining. > > Now, of course, it is possible to find a middle ground that works as a > basis for virtually all languages. In fact, I'd argue that SEH for > Windows actually provides such a layer, and libunwind does too. For > example, a proper implementation of a libunwind personality function > allows you to check whether a given exception originated in your own > language, and just pass it on otherwise (such that e.g. C++ exception > just bubble through a layer of D code). In theory, it would e.g. also be > possible to wrap foreign exceptions in e.g. D Throwable objects to make > them catchable in D code. But the lifetime of the foreign object is > virtually impossible to get right in the general case, and the benefits > of wrapping exceptions like this have turned out not to be worth it, > because it is hard to handle them in a sensible way in the receiving > language (DMD actually does – did? – something like this on Win32). A middle ground would help. In the D/Objective-C implementation there is already an exception bridge for 32bit. The 32bit implementation uses setjmp and longjmp. For transferring D exceptions to Objective-C the compiler sets up a try-catch. Then there's a subclass of NSException (the root exception class in Objective-C) which wraps a D Throwable. This NSException is then thrown using the Objective-C runtime function for throwing exceptions. For transferring exceptions in the other direction bascilly the same thing happens. The compiler uses setjmp and longjmp to catch the Objective-C exception. This is then wrapped as a D exception, a subclass of Throwable, and thrown using the D runtime function for throwing exceptions. For 64bit, Objective-C uses the same exception handling as C++. So I need to somehow be able to catch Objective-C exceptions and Objective-C need to be able to catch D exceptions. Although I still expect to need to wrap the exceptions, since D code won't be expecting to catch instances of NSException, which doesn't inherit from Throwable. Same on the Objective-C side. If D would use the C++ exception handling model I hope that the implementation would be a lot simpler. -- /Jacob Carlborg |
April 09, 2014 Re: Use C++ exception model in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Brad Roberts | On Tuesday, 8 April 2014 at 20:07:09 UTC, Brad Roberts wrote:
> Most of the areas where DMD is 'odd' are a case of "I can't figure out the right way, so any way is better than no way". That's particularly true for var args and eh. I'm confident that pulls that fix these issues can and will be accepted. I'm less confident that someone will volunteer to fix it, but it's something I care about.
The problem is that there are only very few people who are familiar enough with the DMD backend to work on such changes.
And quite understandably so – to be quite honest, I myself am not particularly interested in spending a nontrivial amount of time to get acquainted with a dated, sparsely documented codebase that I will not be able to use in other projects. It certainly is an interesting piece of software and getting acquainted with its internals is probably a nice intellectual exercise, but so far, most people interested in tackling the ABI situation are already busy with another backend.
Sure, one way to go about this would be to just sit down and implement a common ABI in GDC and LDC (hackathon at London/Zürich/… anyone?) and then hope that some random contributor turns up later on and fixes DMD to conform to the standard we agreed on. But this does not necessarily strike me as a productive gamble…
David
|
April 09, 2014 Re: Use C++ exception model in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Iain Buclaw | On Tuesday, 8 April 2014 at 22:19:06 UTC, Iain Buclaw wrote:
> Worse, there's even work that is complete for GDC that is critical for
> ARM support, but breaks ABI - in a positive way that means all targets
> behave as expected. However DMD is impeding progress of this work.
What are you referring to here specifically?
David
|
April 09, 2014 Re: Use C++ exception model in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Wednesday, 9 April 2014 at 07:19:54 UTC, Jacob Carlborg wrote:
> For 64bit, Objective-C uses the same exception handling as C++. So I need to somehow be able to catch Objective-C exceptions and Objective-C need to be able to catch D exceptions. Although I still expect to need to wrap the exceptions, since D code won't be expecting to catch instances of NSException, which doesn't inherit from Throwable. Same on the Objective-C side.
>
> If D would use the C++ exception handling model I hope that the implementation would be a lot simpler.
So, in the last paragraph, you are specifically referring to DMD on x86_64?
David
|
April 09, 2014 Re: Use C++ exception model in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On 9 April 2014 08:19, Jacob Carlborg <doob@me.com> wrote:
> On 08/04/14 14:03, David Nadlinger wrote:
>>
>> On Tuesday, 8 April 2014 at 10:08:24 UTC, Jacob Carlborg wrote:
>>>
>>> Is there a reason to not use the same model, or what's required to be compatible?
>>
>>
>> In short, the reason not to use the same "model" (you could argue that the model is the same, as only the personality functions differ) is that the exception unwinder is intimately tied to both the target language ABI and semantics.
>>
>> For example, all unwinders need to handle the run-time type information for the exception object to correctly dispatch it. And while e.g. the GNU C++ unwinding implementation needs to pull shenanigans to implement the crazy C++ exception lifetime model (cf. catching by reference vs. by value) and enforce throws(...) specifications, the D unwinder needs to understand the difference between Exception and Error and correctly implement exception chaining.
>>
>> Now, of course, it is possible to find a middle ground that works as a basis for virtually all languages. In fact, I'd argue that SEH for Windows actually provides such a layer, and libunwind does too. For example, a proper implementation of a libunwind personality function allows you to check whether a given exception originated in your own language, and just pass it on otherwise (such that e.g. C++ exception just bubble through a layer of D code). In theory, it would e.g. also be possible to wrap foreign exceptions in e.g. D Throwable objects to make them catchable in D code. But the lifetime of the foreign object is virtually impossible to get right in the general case, and the benefits of wrapping exceptions like this have turned out not to be worth it, because it is hard to handle them in a sensible way in the receiving language (DMD actually does - did? - something like this on Win32).
>
>
> A middle ground would help. In the D/Objective-C implementation there is already an exception bridge for 32bit. The 32bit implementation uses setjmp and longjmp.
>
The "middle-ground" would be us handling Objective-C foreign exceptions in our EH personality function.
|
April 09, 2014 Re: Use C++ exception model in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Nadlinger | On 9 April 2014 09:23, David Nadlinger <code@klickverbot.at> wrote:
> On Tuesday, 8 April 2014 at 22:19:06 UTC, Iain Buclaw wrote:
>>
>> Worse, there's even work that is complete for GDC that is critical for ARM support, but breaks ABI - in a positive way that means all targets behave as expected. However DMD is impeding progress of this work.
>
>
> What are you referring to here specifically?
>
LTR side effects on array ops. :o)
|
April 09, 2014 Re: Use C++ exception model in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Nadlinger | "David Nadlinger" wrote in message news:bivyxqzewidjylastzbs@forum.dlang.org... > Sure, one way to go about this would be to just sit down and implement a common ABI in GDC and LDC (hackathon at London/Zürich/… anyone?) and then hope that some random contributor turns up later on and fixes DMD to conform to the standard we agreed on. But this does not necessarily strike me as a productive gamble… You could always go the other way and change GDC and LDC to match what DMD does. :) |
April 09, 2014 Re: Use C++ exception model in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Murphy | Am Wed, 9 Apr 2014 23:11:08 +1000 schrieb "Daniel Murphy" <yebbliesnospam@gmail.com>: > "David Nadlinger" wrote in message news:bivyxqzewidjylastzbs@forum.dlang.org... > > > Sure, one way to go about this would be to just sit down and implement a common ABI in GDC and LDC (hackathon at London/Zürich/… anyone?) and then hope that some random contributor turns up later on and fixes DMD to conform to the standard we agreed on. But this does not necessarily strike me as a productive gamble… > > You could always go the other way and change GDC and LDC to match what DMD does. :) And precisely that is not always possible. E.g. GCC developers have decided against "naked" asm functions. And this out-contract-accessing-caller-scope thing that David mentioned looks like it could pose trouble with LLVM and/or GCC. A common ground has to be found that likely changes the ABI in all 3 compilers. DMD is actually least restricted by the lack of vetoing "upstream" developers :) -- Marco |
April 09, 2014 Re: Use C++ exception model in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marco Leise | On 9 April 2014 14:54, Marco Leise <Marco.Leise@gmx.de> wrote: > Am Wed, 9 Apr 2014 23:11:08 +1000 > schrieb "Daniel Murphy" <yebbliesnospam@gmail.com>: > >> "David Nadlinger" wrote in message news:bivyxqzewidjylastzbs@forum.dlang.org... >> >> > Sure, one way to go about this would be to just sit down and implement a common ABI in GDC and LDC (hackathon at London/Zürich/... anyone?) and then hope that some random contributor turns up later on and fixes DMD to conform to the standard we agreed on. But this does not necessarily strike me as a productive gamble... >> >> You could always go the other way and change GDC and LDC to match what DMD does. :) > > And precisely that is not always possible. E.g. GCC developers have decided against "naked" asm functions. And this Naked exists, just not for x86. :o) > out-contract-accessing-caller-scope thing that David mentioned looks like it could pose trouble with LLVM and/or GCC. It *does* pose trouble. I've just never pointed it out before because GDC builds the stack frame in the front-end (the middle end never got it right anyway because of delegates). The one thing we *do* rely on is that the D front-end marks all closure vars correctly, even if a closure is not required for the function. > A common ground has to be found that likely changes the ABI in all 3 compilers. DMD is actually least restricted by the lack of vetoing "upstream" developers :) > I have only vetoed features that are tied to a specific architecture. This is not unreasonable in my eyes. |
Copyright © 1999-2021 by the D Language Foundation