D as a Better C

Michael V. Franklin via Digitalmars-d-announce digitalmars-d-announce at puremagic.com
Tue Aug 29 19:19:21 PDT 2017


On Wednesday, 30 August 2017 at 00:29:19 UTC, Parke wrote:

> But my original question was about what you (Kagamin) called
> "intermediate D".  I was trying to understand what 
> "intermediate D"
> is, and whether or not I could use "intermediate D" (whatever 
> it is)
> to produce small(er) executables.

"Intermediate D" probably refers to not use the -betterC switch, 
not linking in the official druntime, and instead implementing 
the features of D required by your program yourself.

For example, the following is the most minimal "Hello World" I 
can make with D that does not require the -betterC switch, and 
does not use the official D runtime.  Instead the runtime 
features required by this program are implemented in object.d.

object.d
--------
module object;

alias immutable(char)[] string;

struct ModuleInfo { }

class Object { }

class TypeInfo
{
     bool equals(in void* p1, in void* p2) const
     {
         return p1 == p2;
     }

     int compare(in void* p1, in void* p2) const
     {
         return _xopCmp(p1, p2);
     }
}

class TypeInfo_Class : TypeInfo
{
     ubyte[136] ignore;
}

alias TypeInfo_Class ClassInfo;

class TypeInfo_Struct : TypeInfo
{
     ubyte[120] ignore;
}

extern (C) Object _d_newclass(const ClassInfo ci)
{
     return null;
}

extern(C) void _d_throwc(Object h) { }

class Throwable { }

class Error : Throwable
{
     this(string x)
     { }
}

extern(C) void _d_throwdwarf(Throwable o) { }

extern(C) void _d_dso_registry(void* data) { }


// The following code basically replaces the C runtime
//----------------------------------------------------
extern extern(C) int main(int argc, char** argv);

extern(C) void sys_exit(long arg1)
{
     asm
     {
         mov RAX, 60;
         mov RDI, arg1;
         syscall;
     }
}

extern(C) void _start()
{
     auto ret = main(0, null);
     sys_exit(ret);
}

private alias extern(C) int function(char[][] args) MainFunc;

extern (C) int _d_run_main(int argc, char **argv, MainFunc 
mainFunc)
{
     // ignore args for now
     return mainFunc(null);
}

main.d
------
module main;

long sys_write(long arg1, in void* arg2, long arg3)
{
     long result;

     asm
     {
         mov RAX, 1;
         mov RDI, arg1;
         mov RSI, arg2;
         mov RDX, arg3;
         syscall;
     }

     return result;
}

void write(in string text)
{
     sys_write(2, text.ptr, text.length);
}

void main()
{
     write("Hello\n");
}

Building and executing
----------------------
On Linux 64-bit compile with:
$ dmd -c -fPIC -release object.d main.d -of=main.o

Link with:
$ ld main.o -o main

Report size:
$ size main
    text    data     bss     dec     hex filename
    1070    1872       8    2950     b86 main

Text execution:
$ ./main
Hello

If you link with:
$ ld main.o -o main --gc-sections

You end up with:
$ size main
    text    data     bss     dec     hex filename
     950    1688       0    2638     a4e main


This illustration does not require -betterC, but instead requires 
you to implement a "minimal D runtime" specific to your program, 
and the features of D that it employs.  In this illustration that 
"minimal D runtime" is object.d.

As you can see it is not a polished experience and gets much 
worse when you start employing more features of D.  This could be 
improved, and in fact, with GDC you need even less useless 
boilerplate in object.d and may end up with an even smaller 
executable. (Maybe I'll follow up later with GDC illustration.  
Right now I don't have a computer with the latest GDC installed). 
  If you try this experiment with LDC, you may end up with a 
multi-gigabyte file and crash your PC due to 
https://github.com/ldc-developers/ldc/issues/781

Hopefully we can improve the compiler/runtime implementation so 
doing this kind of programming won't require so many useless 
stubs, and users can implement just the features of D that they 
need for their program without having to rely on the on the blunt 
and heavy hand of -betterC.

Mike



More information about the Digitalmars-d-announce mailing list