Difference between revisions of "Runtime internals"

From D Wiki
Jump to: navigation, search
(Added D program startup sequence)
m (Sequence)
 
(4 intermediate revisions by the same user not shown)
Line 12: Line 12:
  
  
* "D main". This is the `main` function provided by the user in nearly every D program.  It is D-mangled making it distinguishable from C main above.   
+
* "D main" - This is the <code>main</code> function provided by the user in nearly every D program.  It is D-mangled making it distinguishable from C main above.   
 
<syntaxhighlight lang="D">int main(char[][] args)</syntaxhighlight>
 
<syntaxhighlight lang="D">int main(char[][] args)</syntaxhighlight>
  
Line 29: Line 29:
  
 
* [https://github.com/D-Programming-Language/druntime/blob/master/src/rt/dmain2.d#L290 <code>_d_run_main</code>] orchestrates the calling sequence of <code>rt_init()</code>, ''D main'', and <code>rt_term()</code>.  <code>mainFunc</code> is a pointer to ''D main''.
 
* [https://github.com/D-Programming-Language/druntime/blob/master/src/rt/dmain2.d#L290 <code>_d_run_main</code>] orchestrates the calling sequence of <code>rt_init()</code>, ''D main'', and <code>rt_term()</code>.  <code>mainFunc</code> is a pointer to ''D main''.
<syntaxhighlight lang="D">int _d_run_main(int argc, char **argv, void* mainFunc)</syntaxhighlight>  
+
<syntaxhighlight lang="D">int _d_run_main(int argc, char **argv, void* mainFunc)</syntaxhighlight>
  
 
=== Sequence ===
 
=== Sequence ===
 
The following pseudocode illustrates the calling sequence of the symbols above.
 
The following pseudocode illustrates the calling sequence of the symbols above.
  
Every D program is started as if it were a C program.  On Linux, the operating system calls _start which is defined the C Runtime.  After performing C program initialization, the C Runtime calls C main just like a typical C program.
+
Every D program is started as if it were a C program.  On Linux, the operating system calls <code>_start</code> which is defined the C Runtime.  After performing C program initialization, the C Runtime calls ''C main'' just like a typical C program.
  
 
<syntaxhighlight lang="D">
 
<syntaxhighlight lang="D">
Line 48: Line 48:
 
int _d_run_main(int argc, char **argv, MainFunc mainFunc)
 
int _d_run_main(int argc, char **argv, MainFunc mainFunc)
 
{
 
{
     // 3. D some operating-system-specific logic to change argc and argv
+
     // 3. the D Runtime does some operating-system-specific logic to  
     // to char[][] args
+
     // convert argc and argv to char[][] args
 
     char[][] args;
 
     char[][] args;
 
      
 
      
     // 4. Do D runtime initialization
+
     // 4. D Runtime initialization
 
     int result = EXIT_FAILURE;
 
     int result = EXIT_FAILURE;
     if(rt_init()
+
     if(rt_init())
 
     {
 
     {
 
         // 5. call D main
 
         // 5. call D main
Line 60: Line 60:
 
     }
 
     }
 
      
 
      
     // 6.  unwind runtime initialization
+
     // 6.  unwind D Runtime initialization
 
     if (!rt_term())
 
     if (!rt_term())
 
     {
 
     {
Line 66: Line 66:
 
     }
 
     }
 
      
 
      
     // 7. Return to C main
+
     // 7. return to C main
 
     return result;
 
     return result;
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>

Latest revision as of 09:21, 24 May 2015

List of compiler hooks

Runtime Hooks

D program startup sequence

This section provides a general overview of a typical D program's startup sequence. Each operating system and compiler implements this procedure slightly differently, but the fundamental procedure is the same.

Symbols

The startup sequence is essentially an orchestration of the following symbols:

extern(C) void main(int argc, char **argv)


  • "D main" - This is the main function provided by the user in nearly every D program. It is D-mangled making it distinguishable from C main above.
int main(char[][] args)


int _Dmain(char[][] args)


  • rt_init() is the function called before D main to initialize the D Runtime. The D runtime initialization procedure is quite complex and out of scope for this document.
extern(C) int rt_init()


  • rt_term() is the function called after D main to unwind the initialization of the D Runtime.
extern(C) int rt_term()


  • _d_run_main orchestrates the calling sequence of rt_init(), D main, and rt_term(). mainFunc is a pointer to D main.
int _d_run_main(int argc, char **argv, void* mainFunc)

Sequence

The following pseudocode illustrates the calling sequence of the symbols above.

Every D program is started as if it were a C program. On Linux, the operating system calls _start which is defined the C Runtime. After performing C program initialization, the C Runtime calls C main just like a typical C program.

// 1.  _start calls C main
extern(C) void main(int argc, char **argv)
{
    // 2. C main calls _d_run_main passing program arguments and a pointer
    // to D main
    return _d_run_main(argc, argv, &_Dmain);    
}

alias extern(C) int function(char[][] args) MainFunc;
int _d_run_main(int argc, char **argv, MainFunc mainFunc)
{
    // 3. the D Runtime does some operating-system-specific logic to 
    // convert argc and argv to char[][] args
    char[][] args;
    
    // 4. D Runtime initialization
    int result = EXIT_FAILURE;
    if(rt_init())
    {
        // 5. call D main
        result = mainFunc(args);
    }
    
    // 6.  unwind D Runtime initialization
    if (!rt_term())
    {
        result = (result == EXIT_SUCCESS) ? EXIT_FAILURE : result;
    }
    
    // 7. return to C main
    return result;
}