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