Mercurial > projects > ldc
annotate lphobos/std/moduleinit.d @ 193:aca17e55b7a5 trunk
[svn r209] Fixed: exotic array to pointer casts were broken.
Changed: classes now have opaque vtables.
author | lindquist |
---|---|
date | Mon, 12 May 2008 18:44:11 +0200 |
parents | 56a21f3e5d3e |
children | 373489eeaf90 |
rev | line source |
---|---|
89 | 1 // Modified for LLVMDC |
2 | |
3 module std.moduleinit; | |
4 | |
5 //debug = 1; | |
6 | |
7 private | |
8 { | |
9 import object; | |
10 import std.c.stdio; | |
11 import std.c.stdlib; | |
12 } | |
13 | |
14 enum | |
15 { MIctorstart = 1, // we've started constructing it | |
16 MIctordone = 2, // finished construction | |
17 MIstandalone = 4, // module ctor does not depend on other module | |
18 // ctors being done first | |
19 } | |
20 | |
116
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
89
diff
changeset
|
21 // had to move the class to object.d, as its declaration is needed in the compiler code, |
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
89
diff
changeset
|
22 // otherwise the DMDFE Module::moduleinfo member is NULL |
89 | 23 |
24 class ModuleCtorError : Exception | |
25 { | |
26 this(ModuleInfo m) | |
27 { | |
28 super("circular initialization dependency with module " ~ m.name); | |
29 } | |
30 } | |
31 | |
32 | |
117 | 33 // this gets initialized in _moduleCtor() |
89 | 34 extern (C) ModuleInfo[] _moduleinfo_array; |
35 | |
117 | 36 // this method returns the linker constructed, null terminated, array of moduleinfos |
37 extern (C) void** _d_get_moduleinfo_array(); | |
89 | 38 |
39 ModuleInfo[] _moduleinfo_dtors; | |
40 uint _moduleinfo_dtors_i; | |
41 | |
42 // Register termination function pointers | |
43 extern (C) int _fatexit(void *); | |
44 | |
45 /************************************* | |
46 * Initialize the modules. | |
47 */ | |
48 | |
49 extern (C) void _moduleCtor() | |
50 { | |
51 debug printf("_moduleCtor()\n"); | |
52 int len = 0; | |
53 | |
117 | 54 ModuleInfo* mrbegin = cast(ModuleInfo*)_d_get_moduleinfo_array(); |
55 assert(mrbegin !is null); | |
56 | |
57 ModuleInfo* mr; | |
58 for (mr = mrbegin; *mr !is null; ++mr) | |
89 | 59 len++; |
60 _moduleinfo_array = new ModuleInfo[len]; | |
61 len = 0; | |
117 | 62 for (mr = mrbegin; *mr !is null; ++mr) |
63 { _moduleinfo_array[len] = *mr; | |
89 | 64 len++; |
65 } | |
66 | |
67 version (Win32) | |
68 { | |
69 // Ensure module destructors also get called on program termination | |
70 //_fatexit(&_STD_moduleDtor); | |
71 } | |
72 | |
117 | 73 _moduleinfo_dtors = new ModuleInfo[len]; |
89 | 74 debug printf("_moduleinfo_dtors = x%x\n", cast(void *)_moduleinfo_dtors); |
75 _moduleCtor2(_moduleinfo_array, 0); | |
76 | |
77 version (none) | |
78 { | |
79 foreach (m; _moduleinfo_array) | |
80 { | |
81 writefln("module %s, %d", m.name, m.localClasses.length); | |
82 foreach (c; m.localClasses) | |
83 { | |
84 writefln("\tclass %s", c.name); | |
85 } | |
86 } | |
87 } | |
88 } | |
89 | |
90 void _moduleCtor2(ModuleInfo[] mi, int skip) | |
91 { | |
92 debug printf("_moduleCtor2(): %d modules\n", mi.length); | |
93 for (uint i = 0; i < mi.length; i++) | |
94 { | |
95 ModuleInfo m = mi[i]; | |
96 | |
97 debug printf("\tmodule[%d] = '%p'\n", i, m); | |
98 if (!m) | |
99 continue; | |
100 debug printf("\tmodule[%d] = '%.*s'\n", i, m.name); | |
101 if (m.flags & MIctordone) | |
102 continue; | |
103 debug printf("\tmodule[%d] = '%.*s', m = x%x\n", i, m.name, m); | |
104 | |
105 if (m.ctor || m.dtor) | |
106 { | |
107 if (m.flags & MIctorstart) | |
108 { if (skip || m.flags & MIstandalone) | |
109 continue; | |
110 throw new ModuleCtorError(m); | |
111 } | |
112 | |
113 m.flags |= MIctorstart; | |
114 _moduleCtor2(m.importedModules, 0); | |
115 if (m.ctor) | |
116 (*m.ctor)(); | |
117 m.flags &= ~MIctorstart; | |
118 m.flags |= MIctordone; | |
119 | |
120 // Now that construction is done, register the destructor | |
121 //printf("\tadding module dtor x%x\n", m); | |
122 assert(_moduleinfo_dtors_i < _moduleinfo_dtors.length); | |
123 _moduleinfo_dtors[_moduleinfo_dtors_i++] = m; | |
124 } | |
125 else | |
126 { | |
127 m.flags |= MIctordone; | |
128 _moduleCtor2(m.importedModules, 1); | |
129 } | |
130 } | |
131 } | |
132 | |
133 | |
134 /********************************** | |
135 * Destruct the modules. | |
136 */ | |
137 | |
138 // Starting the name with "_STD" means under linux a pointer to the | |
139 // function gets put in the .dtors segment. | |
140 | |
141 extern (C) void _moduleDtor() | |
142 { | |
143 debug printf("_moduleDtor(): %d modules\n", _moduleinfo_dtors_i); | |
144 for (uint i = _moduleinfo_dtors_i; i-- != 0;) | |
145 { | |
146 ModuleInfo m = _moduleinfo_dtors[i]; | |
147 | |
148 debug printf("\tmodule[%d] = '%.*s', x%x\n", i, m.name, m); | |
149 if (m.dtor) | |
150 { | |
151 (*m.dtor)(); | |
152 } | |
153 } | |
154 debug printf("_moduleDtor() done\n"); | |
155 } | |
156 | |
157 /********************************** | |
158 * Run unit tests. | |
159 */ | |
160 | |
161 extern (C) void _moduleUnitTests() | |
162 { | |
163 debug printf("_moduleUnitTests()\n"); | |
164 for (uint i = 0; i < _moduleinfo_array.length; i++) | |
165 { | |
166 ModuleInfo m = _moduleinfo_array[i]; | |
167 | |
168 if (!m) | |
169 continue; | |
170 | |
171 debug printf("\tmodule[%d] = '%.*s'\n", i, m.name); | |
172 if (m.unitTest) | |
173 { | |
174 (*m.unitTest)(); | |
175 } | |
176 } | |
177 } | |
178 |