Mercurial > projects > ldc
comparison druntime/src/compiler/ldc/dmain2.BAK @ 1458:e0b2d67cfe7c
Added druntime (this should be removed once it works).
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Tue, 02 Jun 2009 17:43:06 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1456:7b218ec1044f | 1458:e0b2d67cfe7c |
---|---|
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 memory; | |
16 import util.console; | |
17 import core.stdc.stddef; | |
18 import core.stdc.stdlib; | |
19 import core.stdc.string; | |
20 } | |
21 | |
22 version (Windows) | |
23 { | |
24 extern (Windows) alias int function() FARPROC; | |
25 extern (Windows) FARPROC GetProcAddress(void*, in char*); | |
26 extern (Windows) void* LoadLibraryA(in char*); | |
27 extern (Windows) int FreeLibrary(void*); | |
28 extern (Windows) void* LocalFree(void*); | |
29 extern (Windows) wchar_t* GetCommandLineW(); | |
30 extern (Windows) wchar_t** CommandLineToArgvW(wchar_t*, int*); | |
31 extern (Windows) export int WideCharToMultiByte(uint, uint, wchar_t*, int, char*, int, char*, int); | |
32 pragma(lib, "shell32.lib"); // needed for CommandLineToArgvW | |
33 } | |
34 | |
35 extern (C) void _STI_monitor_staticctor(); | |
36 extern (C) void _STD_monitor_staticdtor(); | |
37 extern (C) void _STI_critical_init(); | |
38 extern (C) void _STD_critical_term(); | |
39 extern (C) void gc_init(); | |
40 extern (C) void gc_term(); | |
41 extern (C) void _minit(); | |
42 extern (C) void _moduleCtor(); | |
43 extern (C) void _moduleDtor(); | |
44 extern (C) void thread_joinAll(); | |
45 | |
46 /*********************************** | |
47 * These are a temporary means of providing a GC hook for DLL use. They may be | |
48 * replaced with some other similar functionality later. | |
49 */ | |
50 extern (C) | |
51 { | |
52 void* gc_getProxy(); | |
53 void gc_setProxy(void* p); | |
54 void gc_clrProxy(); | |
55 | |
56 alias void* function() gcGetFn; | |
57 alias void function(void*) gcSetFn; | |
58 alias void function() gcClrFn; | |
59 } | |
60 | |
61 extern (C) void* rt_loadLibrary(in char[] name) | |
62 { | |
63 version (Windows) | |
64 { | |
65 char[260] temp = void; | |
66 temp[0 .. name.length] = name[]; | |
67 temp[name.length] = cast(char) 0; | |
68 void* ptr = LoadLibraryA(temp.ptr); | |
69 if (ptr is null) | |
70 return ptr; | |
71 gcSetFn gcSet = cast(gcSetFn) GetProcAddress(ptr, "gc_setProxy"); | |
72 if (gcSet !is null) | |
73 gcSet(gc_getProxy()); | |
74 return ptr; | |
75 | |
76 } | |
77 else version (linux) | |
78 { | |
79 throw new Exception("rt_loadLibrary not yet implemented on linux."); | |
80 } | |
81 } | |
82 | |
83 extern (C) bool rt_unloadLibrary(void* ptr) | |
84 { | |
85 version (Windows) | |
86 { | |
87 gcClrFn gcClr = cast(gcClrFn) GetProcAddress(ptr, "gc_clrProxy"); | |
88 if (gcClr !is null) | |
89 gcClr(); | |
90 return FreeLibrary(ptr) != 0; | |
91 } | |
92 else version (linux) | |
93 { | |
94 throw new Exception("rt_unloadLibrary not yet implemented on linux."); | |
95 } | |
96 } | |
97 | |
98 /*********************************** | |
99 * These functions must be defined for any D program linked | |
100 * against this library. | |
101 */ | |
102 extern (C) void onAssertError(string file, size_t line); | |
103 extern (C) void onAssertErrorMsg(string file, size_t line, string msg); | |
104 extern (C) void onRangeError(string file, size_t line); | |
105 extern (C) void onHiddenFuncError(Object o); | |
106 extern (C) void onSwitchError(string file, size_t line); | |
107 extern (C) bool runModuleUnitTests(); | |
108 | |
109 // this function is called from the utf module | |
110 //extern (C) void onUnicodeError(string msg, size_t idx); | |
111 | |
112 /*********************************** | |
113 * These are internal callbacks for various language errors. | |
114 */ | |
115 extern (C) void _d_assert(string file, uint line) | |
116 { | |
117 onAssertError(file, line); | |
118 } | |
119 | |
120 extern (C) static void _d_assert_msg(string msg, string file, uint line) | |
121 { | |
122 onAssertErrorMsg(file, line, msg); | |
123 } | |
124 | |
125 extern (C) void _d_array_bounds(string file, uint line) | |
126 { | |
127 onRangeError(file, line); | |
128 } | |
129 | |
130 extern (C) void _d_switch_error(string file, uint line) | |
131 { | |
132 onSwitchError(file, line); | |
133 } | |
134 | |
135 extern (C) void _d_hidden_func() | |
136 { | |
137 Object o; | |
138 asm | |
139 { | |
140 mov o, EAX; | |
141 } | |
142 onHiddenFuncError(o); | |
143 } | |
144 | |
145 bool _d_isHalting = false; | |
146 | |
147 extern (C) bool rt_isHalting() | |
148 { | |
149 return _d_isHalting; | |
150 } | |
151 | |
152 extern (C) bool rt_trapExceptions = true; | |
153 | |
154 void _d_criticalInit() | |
155 { | |
156 version (linux) | |
157 { | |
158 _STI_monitor_staticctor(); | |
159 _STI_critical_init(); | |
160 } | |
161 } | |
162 | |
163 alias void delegate(Throwable) ExceptionHandler; | |
164 | |
165 extern (C) bool rt_init(ExceptionHandler dg = null) | |
166 { | |
167 _d_criticalInit(); | |
168 | |
169 try | |
170 { | |
171 gc_init(); | |
172 initStaticDataGC(); | |
173 version (Windows) | |
174 _minit(); | |
175 _moduleCtor(); | |
176 return true; | |
177 } | |
178 catch (Throwable e) | |
179 { | |
180 if (dg) | |
181 dg(e); | |
182 } | |
183 catch | |
184 { | |
185 | |
186 } | |
187 _d_criticalTerm(); | |
188 return false; | |
189 } | |
190 | |
191 void _d_criticalTerm() | |
192 { | |
193 version (linux) | |
194 { | |
195 _STD_critical_term(); | |
196 _STD_monitor_staticdtor(); | |
197 } | |
198 } | |
199 | |
200 extern (C) bool rt_term(ExceptionHandler dg = null) | |
201 { | |
202 try | |
203 { | |
204 thread_joinAll(); | |
205 _d_isHalting = true; | |
206 _moduleDtor(); | |
207 gc_term(); | |
208 return true; | |
209 } | |
210 catch (Throwable e) | |
211 { | |
212 if (dg) | |
213 dg(e); | |
214 } | |
215 catch | |
216 { | |
217 | |
218 } | |
219 finally | |
220 { | |
221 _d_criticalTerm(); | |
222 } | |
223 return false; | |
224 } | |
225 | |
226 /*********************************** | |
227 * The D main() function supplied by the user's program | |
228 */ | |
229 int main(char[][] args); | |
230 | |
231 /*********************************** | |
232 * Substitutes for the C main() function. | |
233 * It's purpose is to wrap the call to the D main() | |
234 * function and catch any unhandled exceptions. | |
235 */ | |
236 | |
237 extern (C) int main(int argc, char **argv) | |
238 { | |
239 char[][] args; | |
240 int result; | |
241 | |
242 version (linux) | |
243 { | |
244 _STI_monitor_staticctor(); | |
245 _STI_critical_init(); | |
246 } | |
247 | |
248 version (Windows) | |
249 { | |
250 wchar_t* wcbuf = GetCommandLineW(); | |
251 size_t wclen = wcslen(wcbuf); | |
252 int wargc = 0; | |
253 wchar_t** wargs = CommandLineToArgvW(wcbuf, &wargc); | |
254 assert(wargc == argc); | |
255 | |
256 char* cargp = null; | |
257 size_t cargl = WideCharToMultiByte(65001, 0, wcbuf, wclen, null, 0, null, 0); | |
258 | |
259 cargp = cast(char*) alloca(cargl); | |
260 args = ((cast(char[]*) alloca(wargc * (char[]).sizeof)))[0 .. wargc]; | |
261 | |
262 for (size_t i = 0, p = 0; i < wargc; i++) | |
263 { | |
264 int wlen = wcslen(wargs[i]); | |
265 int clen = WideCharToMultiByte(65001, 0, &wargs[i][0], wlen, null, 0, null, 0); | |
266 args[i] = cargp[p .. p+clen]; | |
267 p += clen; assert(p <= cargl); | |
268 WideCharToMultiByte(65001, 0, &wargs[i][0], wlen, &args[i][0], clen, null, 0); | |
269 } | |
270 LocalFree(wargs); | |
271 wargs = null; | |
272 wargc = 0; | |
273 } | |
274 else version (linux) | |
275 { | |
276 char[]* am = cast(char[]*) malloc(argc * (char[]).sizeof); | |
277 scope(exit) free(am); | |
278 | |
279 for (size_t i = 0; i < argc; i++) | |
280 { | |
281 auto len = strlen(argv[i]); | |
282 am[i] = argv[i][0 .. len]; | |
283 } | |
284 args = am[0 .. argc]; | |
285 } | |
286 | |
287 bool trapExceptions = rt_trapExceptions; | |
288 | |
289 void tryExec(void delegate() dg) | |
290 { | |
291 | |
292 if (trapExceptions) | |
293 { | |
294 try | |
295 { | |
296 dg(); | |
297 } | |
298 catch (Throwable e) | |
299 { | |
300 while (e) | |
301 { | |
302 if (e.file) | |
303 { | |
304 // fprintf(stderr, "%.*s(%u): %.*s\n", e.file, e.line, e.msg); | |
305 console (e.classinfo.name)("@")(e.file)("(")(e.line)("): ")(e.msg)("\n"); | |
306 } | |
307 else | |
308 { | |
309 // fprintf(stderr, "%.*s\n", e.toString()); | |
310 console (e.toString)("\n"); | |
311 } | |
312 if (e.info) | |
313 { | |
314 console ("----------------\n"); | |
315 foreach (t; e.info) | |
316 console (t)("\n"); | |
317 } | |
318 if (e.next) | |
319 console ("\n"); | |
320 e = e.next; | |
321 } | |
322 result = EXIT_FAILURE; | |
323 } | |
324 catch (Object o) | |
325 { | |
326 // fprintf(stderr, "%.*s\n", o.toString()); | |
327 console (o.toString)("\n"); | |
328 result = EXIT_FAILURE; | |
329 } | |
330 } | |
331 else | |
332 { | |
333 dg(); | |
334 } | |
335 } | |
336 | |
337 // NOTE: The lifetime of a process is much like the lifetime of an object: | |
338 // it is initialized, then used, then destroyed. If initialization | |
339 // fails, the successive two steps are never reached. However, if | |
340 // initialization succeeds, then cleanup will occur even if the use | |
341 // step fails in some way. Here, the use phase consists of running | |
342 // the user's main function. If main terminates with an exception, | |
343 // the exception is handled and then cleanup begins. An exception | |
344 // thrown during cleanup, however, will abort the cleanup process. | |
345 | |
346 void runMain() | |
347 { | |
348 result = main(args); | |
349 } | |
350 | |
351 void runAll() | |
352 { | |
353 gc_init(); | |
354 initStaticDataGC(); | |
355 version (Windows) | |
356 _minit(); | |
357 _moduleCtor(); | |
358 if (runModuleUnitTests()) | |
359 tryExec(&runMain); | |
360 thread_joinAll(); | |
361 _d_isHalting = true; | |
362 _moduleDtor(); | |
363 gc_term(); | |
364 } | |
365 | |
366 tryExec(&runAll); | |
367 | |
368 version (linux) | |
369 { | |
370 _STD_critical_term(); | |
371 _STD_monitor_staticdtor(); | |
372 } | |
373 return result; | |
374 } |