Mercurial > projects > ldc
annotate lphobos/std/moduleinit.d @ 117:56a21f3e5d3e trunk
[svn r121] Finished ModuleInfo implementation.
Static ctors/dtors now work according to spec.
Changed class vtable types slightly in some cases. Overridden functions now always take the the type of the first class declaring the method as this parameter. This helps when using headers (w. implementation somewhere else)
author | lindquist |
---|---|
date | Mon, 26 Nov 2007 04:49:23 +0100 |
parents | fd7ad91fd713 |
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 |