Mercurial > projects > ldc
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 } |