comparison runtime/internal/dmain2.d @ 443:44f08170f4ef

Removed tango from the repository and instead added a runtime dir with the files needed to patch and build tango from svn. Reworked the LLVMDC specific pragmas.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Fri, 01 Aug 2008 00:32:06 +0200
parents
children 68be7408a0db
comparison
equal deleted inserted replaced
442:76078c8ab5b9 443:44f08170f4ef
1 /*
2 * Placed into the Public Domain.
3 * written by Walter Bright
4 * www.digitalmars.com
5 */
6
7 /*
8 * Modified by Sean Kelly <sean@f4.ca> for use with Tango.
9 */
10
11 private
12 {
13 import util.console;
14
15 import tango.stdc.stddef;
16 import tango.stdc.stdlib;
17 import tango.stdc.string;
18 }
19
20 version( Win32 )
21 {
22 extern (Windows) void* LocalFree(void*);
23 extern (Windows) wchar_t* GetCommandLineW();
24 extern (Windows) wchar_t** CommandLineToArgvW(wchar_t*, int*);
25 extern (Windows) export int WideCharToMultiByte(uint, uint, wchar_t*, int, char*, int, char*, int);
26 //pragma(lib, "shell32.lib"); // needed for CommandLineToArgvW
27 //pragma(lib, "tango-win32-dmd.lib"); // links Tango's Win32 library to reduce EXE size
28 }
29
30 extern (C) void _STI_monitor_staticctor();
31 extern (C) void _STD_monitor_staticdtor();
32 extern (C) void _STI_critical_init();
33 extern (C) void _STD_critical_term();
34 extern (C) void gc_init();
35 extern (C) void gc_term();
36 extern (C) void _moduleCtor();
37 extern (C) void _moduleDtor();
38 extern (C) void thread_joinAll();
39
40 //debug=PRINTF;
41 debug(PRINTF) extern (C) int printf(char*, ...);
42
43 /***********************************
44 * These functions must be defined for any D program linked
45 * against this library.
46 */
47 extern (C) void onAssertError( char[] file, size_t line );
48 extern (C) void onAssertErrorMsg( char[] file, size_t line, char[] msg );
49 extern (C) void onArrayBoundsError( char[] file, size_t line );
50 extern (C) void onSwitchError( char[] file, size_t line );
51 extern (C) bool runModuleUnitTests();
52
53 // this function is called from the utf module
54 //extern (C) void onUnicodeError( char[] msg, size_t idx );
55
56 /***********************************
57 * These are internal callbacks for various language errors.
58 */
59 extern (C) void _d_assert( char[] file, uint line )
60 {
61 onAssertError( file, line );
62 }
63
64 extern (C) void _d_assert_msg( char[] msg, char[] file, uint line )
65 {
66 onAssertErrorMsg( file, line, msg );
67 }
68
69 extern (C) void _d_array_bounds( char[] file, uint line )
70 {
71 onArrayBoundsError( file, line );
72 }
73
74 extern (C) void _d_switch_error( char[] file, uint line )
75 {
76 onSwitchError( file, line );
77 }
78
79 bool _d_isHalting = false;
80
81 extern (C) bool rt_isHalting()
82 {
83 return _d_isHalting;
84 }
85
86 extern (C) bool rt_trapExceptions = true;
87
88 void _d_criticalInit()
89 {
90 _STI_monitor_staticctor();
91 _STI_critical_init();
92 }
93
94 alias void delegate( Exception ) ExceptionHandler;
95
96 // this is here so users can manually initialize the runtime
97 // for example, when there is no main function etc.
98 extern (C) bool rt_init( ExceptionHandler dg = null )
99 {
100 _d_criticalInit();
101
102 try
103 {
104 gc_init();
105 _moduleCtor();
106 return true;
107 }
108 catch( Exception e )
109 {
110 if( dg )
111 dg( e );
112 }
113 catch
114 {
115
116 }
117 _d_criticalTerm();
118 return false;
119 }
120
121 void _d_criticalTerm()
122 {
123 _STD_critical_term();
124 _STD_monitor_staticdtor();
125 }
126
127 // this is here so users can manually terminate the runtime
128 // for example, when there is no main function etc.
129 extern (C) bool rt_term( ExceptionHandler dg = null )
130 {
131 try
132 {
133 thread_joinAll();
134 _d_isHalting = true;
135 _moduleDtor();
136 gc_term();
137 return true;
138 }
139 catch( Exception e )
140 {
141 if( dg )
142 dg( e );
143 }
144 catch
145 {
146
147 }
148 finally
149 {
150 _d_criticalTerm();
151 }
152 return false;
153 }
154
155 /***********************************
156 * The D main() function supplied by the user's program
157 */
158 int main(char[][] args);
159
160 /***********************************
161 * Substitutes for the C main() function.
162 * It's purpose is to wrap the call to the D main()
163 * function and catch any unhandled exceptions.
164 */
165
166 extern (C) int main(int argc, char **argv, char** env)
167 {
168 char[][] args;
169 int result;
170
171 debug(PRINTF) printf("main ctors\n");
172 _STI_monitor_staticctor();
173 _STI_critical_init();
174
175 debug(PRINTF) printf("main args\n");
176 version (Win32)
177 {
178 wchar_t* wcbuf = GetCommandLineW();
179 size_t wclen = wcslen(wcbuf);
180 int wargc = 0;
181 wchar_t** wargs = CommandLineToArgvW(wcbuf, &wargc);
182 assert(wargc == argc);
183
184 char* cargp = null;
185 size_t cargl = WideCharToMultiByte(65001, 0, wcbuf, wclen, null, 0, null, 0);
186
187 cargp = cast(char*) alloca(cargl);
188 args = ((cast(char[]*) alloca(wargc * (char[]).sizeof)))[0 .. wargc];
189
190 for (size_t i = 0, p = 0; i < wargc; i++)
191 {
192 int wlen = wcslen( wargs[i] );
193 int clen = WideCharToMultiByte(65001, 0, &wargs[i][0], wlen, null, 0, null, 0);
194 args[i] = cargp[p .. p+clen];
195 p += clen; assert(p <= cargl);
196 WideCharToMultiByte(65001, 0, &wargs[i][0], wlen, &args[i][0], clen, null, 0);
197 }
198 LocalFree(wargs);
199 wargs = null;
200 wargc = 0;
201 }
202 else version (linux)
203 {
204 char[]* am = cast(char[]*) malloc(argc * (char[]).sizeof);
205 scope(exit) free(am);
206
207 for (size_t i = 0; i < argc; i++)
208 {
209 auto len = strlen(argv[i]);
210 am[i] = argv[i][0 .. len];
211 }
212 args = am[0 .. argc];
213 }
214
215 debug(PRINTF) printf("main trap exceptions\n");
216 bool trapExceptions = rt_trapExceptions;
217
218 void tryExec(void delegate() dg)
219 {
220 debug(PRINTF) printf("main try exec\n");
221 if (trapExceptions)
222 {
223 try
224 {
225 dg();
226 }
227 catch (Exception e)
228 {
229 while (e)
230 {
231 if (e.file)
232 {
233 debug(PRINTF) printf("%.*s(%u): %.*s\n", e.file.length, e.file.ptr, e.line, e.msg.length, e.msg.ptr);
234 console (e.classinfo.name)("@")(e.file)("(")(e.line)("): ")(e.msg)("\n");
235 }
236 else
237 {
238 // debug(PRINTF) printf("%.*s\n", e.toString());
239 console (e.classinfo.name)(": ")(e.toString)("\n");
240 }
241 e = e.next;
242 }
243 result = EXIT_FAILURE;
244 }
245 catch (Object o)
246 {
247 // fprintf(stderr, "%.*s\n", o.toString());
248 console (o.toString)("\n");
249 result = EXIT_FAILURE;
250 }
251 }
252 else
253 {
254 dg();
255 }
256 }
257
258 // NOTE: The lifetime of a process is much like the lifetime of an object:
259 // it is initialized, then used, then destroyed. If initialization
260 // fails, the successive two steps are never reached. However, if
261 // initialization succeeds, then cleanup will occur even if the use
262 // step fails in some way. Here, the use phase consists of running
263 // the user's main function. If main terminates with an exception,
264 // the exception is handled and then cleanup begins. An exception
265 // thrown during cleanup, however, will abort the cleanup process.
266
267 void runMain()
268 {
269 debug(PRINTF) printf("main runMain\n");
270 result = main(args);
271 }
272
273 void runAll()
274 {
275 debug(PRINTF) printf("main runAll\n");
276 gc_init();
277 _moduleCtor();
278 if (runModuleUnitTests())
279 tryExec(&runMain);
280 thread_joinAll();
281 _d_isHalting = true;
282 _moduleDtor();
283 gc_term();
284 }
285
286 tryExec(&runAll);
287
288 debug(PRINTF) printf("main dtor\n");
289 _STD_critical_term();
290 _STD_monitor_staticdtor();
291
292 return result;
293 }