Difference between revisions of "Runtime internals"
m (Jpf moved page Runtime internald to Runtime internals: typo) |
m (→Sequence) |
||
(5 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
== List of compiler hooks == | == List of compiler hooks == | ||
[[Runtime_Hooks|Runtime Hooks]] | [[Runtime_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: | ||
+ | |||
+ | * "C main" - In DMD and LDC [https://github.com/D-Programming-Language/dmd/blob/14273b311a64247b7406732577338ae52b6fa2a2/src/mars.c#L228 C main seems to be provided by the compiler], while [https://github.com/D-Programming-GDC/GDC/blob/master/libphobos/libdruntime/__entrypoint.di#L60 in GDC it is provided by the D Runtime]. | ||
+ | <syntaxhighlight lang="D">extern(C) void main(int argc, char **argv)</syntaxhighlight> | ||
+ | |||
+ | |||
+ | * "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> | ||
+ | |||
+ | |||
+ | * <code>_Dmain</code> is an alias [https://github.com/D-Programming-Language/dmd/blob/e2106cb61782de1d1c90d7f4ba1038e300164571/src/mangle.c#L542 provided by the compiler] to refer to ''D main''. | ||
+ | <syntaxhighlight lang="D">int _Dmain(char[][] args)</syntaxhighlight> | ||
+ | |||
+ | |||
+ | * [https://github.com/D-Programming-Language/druntime/blob/master/src/rt/dmain2.d#L154 <code>rt_init()</code>] 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. | ||
+ | <syntaxhighlight lang="D">extern(C) int rt_init()</syntaxhighlight> | ||
+ | |||
+ | |||
+ | * [https://github.com/D-Programming-Language/druntime/blob/master/src/rt/dmain2.d#L192 <code>rt_term()</code>] is the function called after ''D main'' to unwind the initialization of the D Runtime. | ||
+ | <syntaxhighlight lang="D">extern(C) int rt_term()</syntaxhighlight> | ||
+ | |||
+ | |||
+ | * [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> | ||
+ | |||
+ | === 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 <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"> | ||
+ | // 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; | ||
+ | } | ||
+ | </syntaxhighlight> |
Latest revision as of 09:21, 24 May 2015
List of compiler 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:
- "C main" - In DMD and LDC C main seems to be provided by the compiler, while in GDC it is provided by the D Runtime.
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)
_Dmain
is an alias provided by the compiler to refer to D main.
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 ofrt_init()
, D main, andrt_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;
}