xdc: A hypothetical D cross-compiler and AST manipulation tool.

Chad Joan chadjoan at gmail.com
Mon Nov 11 19:13:14 PST 2013


On Sunday, 10 November 2013 at 12:24:59 UTC, Daniel Murphy wrote:
> "Andrei Alexandrescu" <SeeWebsiteForEmail at erdani.org> wrote in 
> message
> news:l5n7iq$2op2$1 at digitalmars.com...
>> On 11/9/13 9:37 PM, Daniel Murphy wrote:
>>> "deadalnix" <deadalnix at gmail.com> wrote in message
>>> news:juoauplfttovsmbrafzh at forum.dlang.org...
>>>>
>>>> Out of curiosity, how do you handle exceptions ?
>>>
>>> I didn't.  This was focussed on a subset suitable for 
>>> microcontrollers. I
>>> would probably emit C++ instead if exceptions were required.
>>
>> That doesn't quite rhyme with C being a good backend language 
>> :o).
>>
>> Andrei
>>
>
> I guess it's not for the full language, but if you can't use 
> gdc or llvm,
> chances are your platform is too constrained to use exceptions.
>  I don't
> mean C is capable of representing everything, but it can handle 
> a large and
> useful subset.

My ideal is to have exceptions in C anyways.  I don't understand 
why people are so afraid of this.  It's doable in very portable 
ways, and D's nothrow attribute gives a good hint to the compiler 
that can be used to avoid performance drains in inappropriate 
places.

I think that setjmp/longjmp comes to mind most of the time 
because it is what people would normally use in C if they have to 
write the C code by hand.  This is one approach that I would have 
a compiler optionally emit, controllable by a command-line flag 
(--c-exceptions=sjlj or somesuch).

There is a different approach that I'd want to try first: alter 
the calling convention and always pass an exception object as the 
first argument (but only if the called function can throw).

Given this example:

-----------------------------------------------------------------

float baz(int a);

void foo()
{
     int a = 42;
     // do stuff
     float b = baz(a);
     // do other stuff
}

float bar()
{
     try
         return baz(9);
     catch( Exception e )
         return 0.0;
}

--------------------------------

The D->C compiler would emit code like so:

-----------------------------------------------------------------

float baz(Exception *exception, int a);

void foo(Exception *exception)
{
     int a = 42;
     // do stuff
     float b = baz(exception, a);
     if ( exception->thrown )
         return;
     // do other stuff
}

float bar(Exception *exception)
{
     float result = baz(exception, 9);
     if ( exception->thrown )
         goto ExceptionHandler1;
     return result;

ExceptionHandler1:
     Exception *e = exception;
     (void)e;
     return 0.0;
}

--------------------------------
(Name mangling omitted for the sake of sanity.)

This is not something that you'd want to do by hand when writing 
C-code, though that doesn't stop people from trying to poorly 
approximate it using integer return values ;)

It would integrate nicely with scope, because the compiler would 
know where to put all of the goto statements and labels.

It's also made of pointers, ifs, goto's, and labels: stuff that 
any usable C compiler should have.  Super portable.

The drawback: This would, of course, not link nicely with code 
generated by other D compilers.  I don't mind this at all though, 
because if you're using this then it's probably because there 
aren't any other D compilers supporting your platform anyways.

I've already written a bunch of C code that emulates exception 
handling + scope statements using setjmp/longjmp, and I really 
wish that a compiler could write better optimized C code /for/ me.


More information about the Digitalmars-d mailing list