Mercurial > projects > ldc
annotate lphobos/std/moduleinit.d @ 116:fd7ad91fd713 trunk
[svn r120] ModuleInfo implementation is now almost complete.
Fixed some nasty static array-initializer bugs.
Fixed bug in DtoArrayLen and DtoArrayPtr for full slices of static arrays.
author | lindquist |
---|---|
date | Sun, 25 Nov 2007 18:55:52 +0100 |
parents | ccca1c13e13a |
children | 56a21f3e5d3e |
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 | |
33 // Win32: this gets initialized by minit.asm | |
34 // linux: this gets initialized in _moduleCtor() | |
35 extern (C) ModuleInfo[] _moduleinfo_array; | |
36 | |
37 version (linux) | |
38 { | |
39 // This linked list is created by a compiler generated function inserted | |
40 // into the .ctor list by the compiler. | |
41 struct ModuleReference | |
42 { | |
43 ModuleReference* next; | |
44 ModuleInfo mod; | |
45 } | |
46 | |
47 extern (C) ModuleReference *_Dmodule_ref; // start of linked list | |
48 } | |
49 | |
50 ModuleInfo[] _moduleinfo_dtors; | |
51 uint _moduleinfo_dtors_i; | |
52 | |
53 // Register termination function pointers | |
54 extern (C) int _fatexit(void *); | |
55 | |
56 /************************************* | |
57 * Initialize the modules. | |
58 */ | |
59 | |
60 extern (C) void _moduleCtor() | |
61 { | |
62 debug printf("_moduleCtor()\n"); | |
63 version (linux) | |
64 { | |
65 int len = 0; | |
66 ModuleReference *mr; | |
67 | |
68 for (mr = _Dmodule_ref; mr; mr = mr.next) | |
69 len++; | |
70 _moduleinfo_array = new ModuleInfo[len]; | |
71 len = 0; | |
72 for (mr = _Dmodule_ref; mr; mr = mr.next) | |
73 { _moduleinfo_array[len] = mr.mod; | |
74 len++; | |
75 } | |
76 } | |
77 | |
78 version (Win32) | |
79 { | |
80 // Ensure module destructors also get called on program termination | |
81 //_fatexit(&_STD_moduleDtor); | |
82 } | |
83 | |
84 _moduleinfo_dtors = new ModuleInfo[_moduleinfo_array.length]; | |
85 debug printf("_moduleinfo_dtors = x%x\n", cast(void *)_moduleinfo_dtors); | |
86 _moduleCtor2(_moduleinfo_array, 0); | |
87 | |
88 version (none) | |
89 { | |
90 foreach (m; _moduleinfo_array) | |
91 { | |
92 writefln("module %s, %d", m.name, m.localClasses.length); | |
93 foreach (c; m.localClasses) | |
94 { | |
95 writefln("\tclass %s", c.name); | |
96 } | |
97 } | |
98 } | |
99 } | |
100 | |
101 void _moduleCtor2(ModuleInfo[] mi, int skip) | |
102 { | |
103 debug printf("_moduleCtor2(): %d modules\n", mi.length); | |
104 for (uint i = 0; i < mi.length; i++) | |
105 { | |
106 ModuleInfo m = mi[i]; | |
107 | |
108 debug printf("\tmodule[%d] = '%p'\n", i, m); | |
109 if (!m) | |
110 continue; | |
111 debug printf("\tmodule[%d] = '%.*s'\n", i, m.name); | |
112 if (m.flags & MIctordone) | |
113 continue; | |
114 debug printf("\tmodule[%d] = '%.*s', m = x%x\n", i, m.name, m); | |
115 | |
116 if (m.ctor || m.dtor) | |
117 { | |
118 if (m.flags & MIctorstart) | |
119 { if (skip || m.flags & MIstandalone) | |
120 continue; | |
121 throw new ModuleCtorError(m); | |
122 } | |
123 | |
124 m.flags |= MIctorstart; | |
125 _moduleCtor2(m.importedModules, 0); | |
126 if (m.ctor) | |
127 (*m.ctor)(); | |
128 m.flags &= ~MIctorstart; | |
129 m.flags |= MIctordone; | |
130 | |
131 // Now that construction is done, register the destructor | |
132 //printf("\tadding module dtor x%x\n", m); | |
133 assert(_moduleinfo_dtors_i < _moduleinfo_dtors.length); | |
134 _moduleinfo_dtors[_moduleinfo_dtors_i++] = m; | |
135 } | |
136 else | |
137 { | |
138 m.flags |= MIctordone; | |
139 _moduleCtor2(m.importedModules, 1); | |
140 } | |
141 } | |
142 } | |
143 | |
144 | |
145 /********************************** | |
146 * Destruct the modules. | |
147 */ | |
148 | |
149 // Starting the name with "_STD" means under linux a pointer to the | |
150 // function gets put in the .dtors segment. | |
151 | |
152 extern (C) void _moduleDtor() | |
153 { | |
154 debug printf("_moduleDtor(): %d modules\n", _moduleinfo_dtors_i); | |
155 for (uint i = _moduleinfo_dtors_i; i-- != 0;) | |
156 { | |
157 ModuleInfo m = _moduleinfo_dtors[i]; | |
158 | |
159 debug printf("\tmodule[%d] = '%.*s', x%x\n", i, m.name, m); | |
160 if (m.dtor) | |
161 { | |
162 (*m.dtor)(); | |
163 } | |
164 } | |
165 debug printf("_moduleDtor() done\n"); | |
166 } | |
167 | |
168 /********************************** | |
169 * Run unit tests. | |
170 */ | |
171 | |
172 extern (C) void _moduleUnitTests() | |
173 { | |
174 debug printf("_moduleUnitTests()\n"); | |
175 for (uint i = 0; i < _moduleinfo_array.length; i++) | |
176 { | |
177 ModuleInfo m = _moduleinfo_array[i]; | |
178 | |
179 if (!m) | |
180 continue; | |
181 | |
182 debug printf("\tmodule[%d] = '%.*s'\n", i, m.name); | |
183 if (m.unitTest) | |
184 { | |
185 (*m.unitTest)(); | |
186 } | |
187 } | |
188 } | |
189 |