Use C++ exception model in D

Jacob Carlborg doob at me.com
Wed Apr 9 00:19:53 PDT 2014


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


More information about the Digitalmars-d mailing list