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 }