comparison druntime/src/compiler/dmd/dmain2.d @ 759:d3eb054172f9

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