Mercurial > projects > ldc
annotate tango/lib/compiler/llvmdc/genobj.d @ 323:0d52412d5b1a trunk
[svn r344] Fixed some very minor issues with the usage listing when calling llvmdc with no arguments.
Changed the way moduleinfo is registered to use the same approach as DMD, this eliminates the need for correct linking order and should make the way for using a natively compiled runtime library. This should speed up linking tremendously and should now be possible.
Fixed the llvm.used array to only be emitted if really necessary.
author | lindquist |
---|---|
date | Wed, 09 Jul 2008 23:43:51 +0200 |
parents | 665b81613475 |
children |
rev | line source |
---|---|
132 | 1 /** |
2 * Part of the D programming language runtime library. | |
3 * Forms the symbols available to all D programs. Includes | |
4 * Object, which is the root of the class object hierarchy. | |
5 * | |
6 * This module is implicitly imported. | |
7 * Macros: | |
8 * WIKI = Object | |
9 */ | |
10 | |
11 /* | |
12 * Copyright (C) 2004-2007 by Digital Mars, www.digitalmars.com | |
13 * Written by Walter Bright | |
14 * | |
15 * This software is provided 'as-is', without any express or implied | |
16 * warranty. In no event will the authors be held liable for any damages | |
17 * arising from the use of this software. | |
18 * | |
19 * Permission is granted to anyone to use this software for any purpose, | |
20 * including commercial applications, and to alter it and redistribute it | |
21 * freely, in both source and binary form, subject to the following | |
22 * restrictions: | |
23 * | |
24 * o The origin of this software must not be misrepresented; you must not | |
25 * claim that you wrote the original software. If you use this software | |
26 * in a product, an acknowledgment in the product documentation would be | |
27 * appreciated but is not required. | |
28 * o Altered source versions must be plainly marked as such, and must not | |
29 * be misrepresented as being the original software. | |
30 * o This notice may not be removed or altered from any source | |
31 * distribution. | |
32 */ | |
33 | |
34 /* | |
35 * Modified by Sean Kelly <sean@f4.ca> for use with Tango. | |
275
665b81613475
[svn r296] Removed: the 'suite' dir, it never took off!
lindquist
parents:
272
diff
changeset
|
36 * Modified by Tomas Lindquist Olsen <tomas@famolsen.dk> for use with LLVMDC. |
132 | 37 */ |
38 | |
39 module object; | |
40 | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
41 //debug=PRINTF |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
42 |
132 | 43 private |
44 { | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
45 import tango.stdc.string; // : memcmp, memcpy, memmove; |
132 | 46 import tango.stdc.stdlib; // : calloc, realloc, free; |
47 import util.string; | |
48 debug(PRINTF) import tango.stdc.stdio; // : printf; | |
49 | |
50 extern (C) void onOutOfMemoryError(); | |
51 extern (C) Object _d_newclass(ClassInfo ci); | |
52 } | |
53 | |
54 // NOTE: For some reason, this declaration method doesn't work | |
55 // in this particular file (and this file only). It must | |
56 // be a DMD thing. | |
57 //alias typeof(int.sizeof) size_t; | |
58 //alias typeof(cast(void*)0 - cast(void*)0) ptrdiff_t; | |
59 | |
275
665b81613475
[svn r296] Removed: the 'suite' dir, it never took off!
lindquist
parents:
272
diff
changeset
|
60 version( LLVM64 ) |
132 | 61 { |
62 alias ulong size_t; | |
63 alias long ptrdiff_t; | |
64 } | |
65 else | |
66 { | |
67 alias uint size_t; | |
68 alias int ptrdiff_t; | |
69 } | |
70 | |
71 alias size_t hash_t; | |
72 | |
73 /** | |
74 * All D class objects inherit from Object. | |
75 */ | |
76 class Object | |
77 { | |
78 /** | |
79 * Convert Object to a human readable string. | |
80 */ | |
81 char[] toString() | |
82 { | |
83 return this.classinfo.name; | |
84 } | |
85 | |
86 /** | |
87 * Compute hash function for Object. | |
88 */ | |
89 hash_t toHash() | |
90 { | |
91 // BUG: this prevents a compacting GC from working, needs to be fixed | |
92 return cast(hash_t)cast(void*)this; | |
93 } | |
94 | |
95 /** | |
96 * Compare with another Object obj. | |
97 * Returns: | |
98 * $(TABLE | |
99 * $(TR $(TD this < obj) $(TD < 0)) | |
100 * $(TR $(TD this == obj) $(TD 0)) | |
101 * $(TR $(TD this > obj) $(TD > 0)) | |
102 * ) | |
103 */ | |
104 int opCmp(Object o) | |
105 { | |
106 // BUG: this prevents a compacting GC from working, needs to be fixed | |
107 //return cast(int)cast(void*)this - cast(int)cast(void*)o; | |
108 | |
109 //throw new Exception("need opCmp for class " ~ this.classinfo.name); | |
110 return this !is o; | |
111 } | |
112 | |
113 /** | |
114 * Returns !=0 if this object does have the same contents as obj. | |
115 */ | |
116 int opEquals(Object o) | |
117 { | |
118 return cast(int)(this is o); | |
119 } | |
120 | |
121 interface Monitor | |
122 { | |
123 void lock(); | |
124 void unlock(); | |
125 } | |
126 } | |
127 | |
128 /** | |
129 * Information about an interface. | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
130 * When an object is accessed via an interface, an Interface* appears as the |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
131 * first entry in its vtbl. |
132 | 132 */ |
133 struct Interface | |
134 { | |
135 ClassInfo classinfo; /// .classinfo for this interface (not for containing class) | |
136 void*[] vtbl; | |
137 ptrdiff_t offset; /// offset to Interface 'this' from Object 'this' | |
138 } | |
139 | |
140 /** | |
141 * Runtime type information about a class. Can be retrieved for any class type | |
142 * or instance by using the .classinfo property. | |
143 * A pointer to this appears as the first entry in the class's vtbl[]. | |
144 */ | |
145 class ClassInfo : Object | |
146 { | |
147 byte[] init; /** class static initializer | |
148 * (init.length gives size in bytes of class) | |
149 */ | |
150 char[] name; /// class name | |
151 void*[] vtbl; /// virtual function pointer table | |
152 Interface[] interfaces; /// interfaces this class implements | |
153 ClassInfo base; /// base class | |
154 void* destructor; | |
155 void function(Object) classInvariant; | |
156 uint flags; | |
157 // 1: // IUnknown | |
158 // 2: // has no possible pointers into GC memory | |
159 // 4: // has offTi[] member | |
160 // 8: // has constructors | |
161 void* deallocator; | |
162 OffsetTypeInfo[] offTi; | |
163 void function(Object) defaultConstructor; // default Constructor | |
164 | |
165 /** | |
166 * Search all modules for ClassInfo corresponding to classname. | |
167 * Returns: null if not found | |
168 */ | |
169 static ClassInfo find(char[] classname) | |
170 { | |
171 foreach (m; ModuleInfo) | |
172 { | |
173 //writefln("module %s, %d", m.name, m.localClasses.length); | |
174 foreach (c; m.localClasses) | |
175 { | |
176 //writefln("\tclass %s", c.name); | |
177 if (c.name == classname) | |
178 return c; | |
179 } | |
180 } | |
181 return null; | |
182 } | |
183 | |
184 /** | |
185 * Create instance of Object represented by 'this'. | |
186 */ | |
187 Object create() | |
188 { | |
189 if (flags & 8 && !defaultConstructor) | |
190 return null; | |
191 Object o = _d_newclass(this); | |
192 if (flags & 8 && defaultConstructor) | |
193 { | |
194 defaultConstructor(o); | |
195 } | |
196 return o; | |
197 } | |
198 } | |
199 | |
200 /** | |
201 * Array of pairs giving the offset and type information for each | |
202 * member in an aggregate. | |
203 */ | |
204 struct OffsetTypeInfo | |
205 { | |
206 size_t offset; /// Offset of member from start of object | |
207 TypeInfo ti; /// TypeInfo for this member | |
208 } | |
209 | |
210 /** | |
211 * Runtime type information about a type. | |
212 * Can be retrieved for any type using a | |
213 * <a href="../expression.html#typeidexpression">TypeidExpression</a>. | |
214 */ | |
215 class TypeInfo | |
216 { | |
217 hash_t toHash() | |
218 { hash_t hash; | |
219 | |
220 foreach (char c; this.toString()) | |
221 hash = hash * 9 + c; | |
222 return hash; | |
223 } | |
224 | |
225 int opCmp(Object o) | |
226 { | |
227 if (this is o) | |
228 return 0; | |
229 TypeInfo ti = cast(TypeInfo)o; | |
230 if (ti is null) | |
231 return 1; | |
232 return stringCompare(this.toString(), ti.toString()); | |
233 } | |
234 | |
235 int opEquals(Object o) | |
236 { | |
237 /* TypeInfo instances are singletons, but duplicates can exist | |
238 * across DLL's. Therefore, comparing for a name match is | |
239 * sufficient. | |
240 */ | |
241 if (this is o) | |
242 return 1; | |
243 TypeInfo ti = cast(TypeInfo)o; | |
244 return cast(int)(ti && this.toString() == ti.toString()); | |
245 } | |
246 | |
247 /// Returns a hash of the instance of a type. | |
248 hash_t getHash(void *p) { return cast(hash_t)p; } | |
249 | |
250 /// Compares two instances for equality. | |
251 int equals(void *p1, void *p2) { return cast(int)(p1 == p2); } | |
252 | |
253 /// Compares two instances for <, ==, or >. | |
254 int compare(void *p1, void *p2) { return 0; } | |
255 | |
256 /// Returns size of the type. | |
257 size_t tsize() { return 0; } | |
258 | |
259 /// Swaps two instances of the type. | |
260 void swap(void *p1, void *p2) | |
261 { | |
262 size_t n = tsize(); | |
263 for (size_t i = 0; i < n; i++) | |
264 { byte t; | |
265 | |
266 t = (cast(byte *)p1)[i]; | |
267 (cast(byte *)p1)[i] = (cast(byte *)p2)[i]; | |
268 (cast(byte *)p2)[i] = t; | |
269 } | |
270 } | |
271 | |
272 /// Get TypeInfo for 'next' type, as defined by what kind of type this is, | |
273 /// null if none. | |
274 TypeInfo next() { return null; } | |
275 | |
276 /// Return default initializer, null if default initialize to 0 | |
277 void[] init() { return null; } | |
278 | |
279 /// Get flags for type: 1 means GC should scan for pointers | |
280 uint flags() { return 0; } | |
281 | |
282 /// Get type information on the contents of the type; null if not available | |
283 OffsetTypeInfo[] offTi() { return null; } | |
284 } | |
285 | |
286 class TypeInfo_Typedef : TypeInfo | |
287 { | |
288 char[] toString() { return name; } | |
289 | |
290 int opEquals(Object o) | |
291 { TypeInfo_Typedef c; | |
292 | |
293 return cast(int) | |
294 (this is o || | |
295 ((c = cast(TypeInfo_Typedef)o) !is null && | |
296 this.name == c.name && | |
297 this.base == c.base)); | |
298 } | |
299 | |
300 hash_t getHash(void *p) { return base.getHash(p); } | |
301 int equals(void *p1, void *p2) { return base.equals(p1, p2); } | |
302 int compare(void *p1, void *p2) { return base.compare(p1, p2); } | |
303 size_t tsize() { return base.tsize(); } | |
304 void swap(void *p1, void *p2) { return base.swap(p1, p2); } | |
305 | |
271
1e6e2b5d5bfe
[svn r292] Fixed: string switch was broken in several ways.
lindquist
parents:
213
diff
changeset
|
306 TypeInfo next() { return base; } |
132 | 307 uint flags() { return base.flags(); } |
308 void[] init() { return m_init.length ? m_init : base.init(); } | |
309 | |
310 TypeInfo base; | |
311 char[] name; | |
312 void[] m_init; | |
313 } | |
314 | |
315 class TypeInfo_Enum : TypeInfo_Typedef | |
316 { | |
317 } | |
318 | |
319 class TypeInfo_Pointer : TypeInfo | |
320 { | |
321 char[] toString() { return m_next.toString() ~ "*"; } | |
322 | |
323 int opEquals(Object o) | |
324 { TypeInfo_Pointer c; | |
325 | |
326 return this is o || | |
327 ((c = cast(TypeInfo_Pointer)o) !is null && | |
328 this.m_next == c.m_next); | |
329 } | |
330 | |
331 hash_t getHash(void *p) | |
332 { | |
333 return cast(hash_t)*cast(void**)p; | |
334 } | |
335 | |
336 int equals(void *p1, void *p2) | |
337 { | |
338 return cast(int)(*cast(void* *)p1 == *cast(void* *)p2); | |
339 } | |
340 | |
341 int compare(void *p1, void *p2) | |
342 { | |
343 if (*cast(void* *)p1 < *cast(void* *)p2) | |
344 return -1; | |
345 else if (*cast(void* *)p1 > *cast(void* *)p2) | |
346 return 1; | |
347 else | |
348 return 0; | |
349 } | |
350 | |
351 size_t tsize() | |
352 { | |
353 return (void*).sizeof; | |
354 } | |
355 | |
356 void swap(void *p1, void *p2) | |
357 { void* tmp; | |
358 tmp = *cast(void**)p1; | |
359 *cast(void**)p1 = *cast(void**)p2; | |
360 *cast(void**)p2 = tmp; | |
361 } | |
362 | |
363 TypeInfo next() { return m_next; } | |
364 uint flags() { return 1; } | |
365 | |
366 TypeInfo m_next; | |
367 } | |
368 | |
369 class TypeInfo_Array : TypeInfo | |
370 { | |
371 char[] toString() { return value.toString() ~ "[]"; } | |
372 | |
373 int opEquals(Object o) | |
374 { TypeInfo_Array c; | |
375 | |
376 return cast(int) | |
377 (this is o || | |
378 ((c = cast(TypeInfo_Array)o) !is null && | |
379 this.value == c.value)); | |
380 } | |
381 | |
382 hash_t getHash(void *p) | |
383 { size_t sz = value.tsize(); | |
384 hash_t hash = 0; | |
385 void[] a = *cast(void[]*)p; | |
386 for (size_t i = 0; i < a.length; i++) | |
387 hash += value.getHash(a.ptr + i * sz); | |
388 return hash; | |
389 } | |
390 | |
391 int equals(void *p1, void *p2) | |
392 { | |
393 void[] a1 = *cast(void[]*)p1; | |
394 void[] a2 = *cast(void[]*)p2; | |
395 if (a1.length != a2.length) | |
396 return 0; | |
397 size_t sz = value.tsize(); | |
398 for (size_t i = 0; i < a1.length; i++) | |
399 { | |
400 if (!value.equals(a1.ptr + i * sz, a2.ptr + i * sz)) | |
401 return 0; | |
402 } | |
403 return 1; | |
404 } | |
405 | |
406 int compare(void *p1, void *p2) | |
407 { | |
408 void[] a1 = *cast(void[]*)p1; | |
409 void[] a2 = *cast(void[]*)p2; | |
410 size_t sz = value.tsize(); | |
411 size_t len = a1.length; | |
412 | |
413 if (a2.length < len) | |
414 len = a2.length; | |
415 for (size_t u = 0; u < len; u++) | |
416 { | |
417 int result = value.compare(a1.ptr + u * sz, a2.ptr + u * sz); | |
418 if (result) | |
419 return result; | |
420 } | |
421 return cast(int)a1.length - cast(int)a2.length; | |
422 } | |
423 | |
424 size_t tsize() | |
425 { | |
426 return (void[]).sizeof; | |
427 } | |
428 | |
429 void swap(void *p1, void *p2) | |
430 { void[] tmp; | |
431 tmp = *cast(void[]*)p1; | |
432 *cast(void[]*)p1 = *cast(void[]*)p2; | |
433 *cast(void[]*)p2 = tmp; | |
434 } | |
435 | |
436 TypeInfo value; | |
437 | |
438 TypeInfo next() | |
439 { | |
440 return value; | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
441 } |
132 | 442 |
443 uint flags() { return 1; } | |
444 } | |
445 | |
446 class TypeInfo_StaticArray : TypeInfo | |
447 { | |
448 char[] toString() | |
449 { | |
450 char [10] tmp = void; | |
451 return value.toString() ~ "[" ~ intToUtf8(tmp, len) ~ "]"; | |
452 } | |
453 | |
454 int opEquals(Object o) | |
455 { TypeInfo_StaticArray c; | |
456 | |
457 return cast(int) | |
458 (this is o || | |
459 ((c = cast(TypeInfo_StaticArray)o) !is null && | |
460 this.len == c.len && | |
461 this.value == c.value)); | |
462 } | |
463 | |
464 hash_t getHash(void *p) | |
465 { size_t sz = value.tsize(); | |
466 hash_t hash = 0; | |
467 for (size_t i = 0; i < len; i++) | |
468 hash += value.getHash(p + i * sz); | |
469 return hash; | |
470 } | |
471 | |
472 int equals(void *p1, void *p2) | |
473 { | |
474 size_t sz = value.tsize(); | |
475 | |
476 for (size_t u = 0; u < len; u++) | |
477 { | |
478 if (!value.equals(p1 + u * sz, p2 + u * sz)) | |
479 return 0; | |
480 } | |
481 return 1; | |
482 } | |
483 | |
484 int compare(void *p1, void *p2) | |
485 { | |
486 size_t sz = value.tsize(); | |
487 | |
488 for (size_t u = 0; u < len; u++) | |
489 { | |
490 int result = value.compare(p1 + u * sz, p2 + u * sz); | |
491 if (result) | |
492 return result; | |
493 } | |
494 return 0; | |
495 } | |
496 | |
497 size_t tsize() | |
498 { | |
499 return len * value.tsize(); | |
500 } | |
501 | |
502 void swap(void *p1, void *p2) | |
503 { void* tmp; | |
504 size_t sz = value.tsize(); | |
505 ubyte[16] buffer; | |
506 void* pbuffer; | |
507 | |
508 if (sz < buffer.sizeof) | |
509 tmp = buffer.ptr; | |
510 else | |
511 tmp = pbuffer = (new void[sz]).ptr; | |
512 | |
513 for (size_t u = 0; u < len; u += sz) | |
514 { size_t o = u * sz; | |
515 memcpy(tmp, p1 + o, sz); | |
516 memcpy(p1 + o, p2 + o, sz); | |
517 memcpy(p2 + o, tmp, sz); | |
518 } | |
519 if (pbuffer) | |
520 delete pbuffer; | |
521 } | |
522 | |
523 void[] init() { return value.init(); } | |
524 TypeInfo next() { return value; } | |
525 uint flags() { return value.flags(); } | |
526 | |
527 TypeInfo value; | |
528 size_t len; | |
529 } | |
530 | |
531 class TypeInfo_AssociativeArray : TypeInfo | |
532 { | |
533 char[] toString() | |
534 { | |
535 return next.toString() ~ "[" ~ key.toString() ~ "]"; | |
536 } | |
537 | |
538 int opEquals(Object o) | |
539 { TypeInfo_AssociativeArray c; | |
540 | |
541 return this is o || | |
542 ((c = cast(TypeInfo_AssociativeArray)o) !is null && | |
543 this.key == c.key && | |
544 this.value == c.value); | |
545 } | |
546 | |
547 // BUG: need to add the rest of the functions | |
548 | |
549 size_t tsize() | |
550 { | |
551 return (char[int]).sizeof; | |
552 } | |
553 | |
554 TypeInfo next() { return value; } | |
555 uint flags() { return 1; } | |
556 | |
557 TypeInfo value; | |
558 TypeInfo key; | |
559 } | |
560 | |
561 class TypeInfo_Function : TypeInfo | |
562 { | |
563 char[] toString() | |
564 { | |
565 return next.toString() ~ "()"; | |
566 } | |
567 | |
568 int opEquals(Object o) | |
569 { TypeInfo_Function c; | |
570 | |
571 return this is o || | |
572 ((c = cast(TypeInfo_Function)o) !is null && | |
573 this.next == c.next); | |
574 } | |
575 | |
576 // BUG: need to add the rest of the functions | |
577 | |
578 size_t tsize() | |
579 { | |
580 return 0; // no size for functions | |
581 } | |
582 | |
583 TypeInfo next; | |
584 } | |
585 | |
586 class TypeInfo_Delegate : TypeInfo | |
587 { | |
588 char[] toString() | |
589 { | |
590 return next.toString() ~ " delegate()"; | |
591 } | |
592 | |
593 int opEquals(Object o) | |
594 { TypeInfo_Delegate c; | |
595 | |
596 return this is o || | |
597 ((c = cast(TypeInfo_Delegate)o) !is null && | |
598 this.next == c.next); | |
599 } | |
600 | |
601 // BUG: need to add the rest of the functions | |
602 | |
603 size_t tsize() | |
604 { alias int delegate() dg; | |
605 return dg.sizeof; | |
606 } | |
607 | |
608 uint flags() { return 1; } | |
609 | |
610 TypeInfo next; | |
611 } | |
612 | |
613 class TypeInfo_Class : TypeInfo | |
614 { | |
615 char[] toString() { return info.name; } | |
616 | |
617 int opEquals(Object o) | |
618 { TypeInfo_Class c; | |
619 | |
620 return this is o || | |
621 ((c = cast(TypeInfo_Class)o) !is null && | |
622 this.info.name == c.classinfo.name); | |
623 } | |
624 | |
625 hash_t getHash(void *p) | |
626 { | |
627 Object o = *cast(Object*)p; | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
628 return o ? o.toHash() : 0; |
132 | 629 } |
630 | |
631 int equals(void *p1, void *p2) | |
632 { | |
633 Object o1 = *cast(Object*)p1; | |
634 Object o2 = *cast(Object*)p2; | |
635 | |
636 return (o1 is o2) || (o1 && o1.opEquals(o2)); | |
637 } | |
638 | |
639 int compare(void *p1, void *p2) | |
640 { | |
641 Object o1 = *cast(Object*)p1; | |
642 Object o2 = *cast(Object*)p2; | |
643 int c = 0; | |
644 | |
645 // Regard null references as always being "less than" | |
646 if (o1 !is o2) | |
647 { | |
648 if (o1) | |
649 { if (!o2) | |
650 c = 1; | |
651 else | |
652 c = o1.opCmp(o2); | |
653 } | |
654 else | |
655 c = -1; | |
656 } | |
657 return c; | |
658 } | |
659 | |
660 size_t tsize() | |
661 { | |
662 return Object.sizeof; | |
663 } | |
664 | |
665 uint flags() { return 1; } | |
666 | |
667 OffsetTypeInfo[] offTi() | |
668 { | |
669 return (info.flags & 4) ? info.offTi : null; | |
670 } | |
671 | |
672 ClassInfo info; | |
673 } | |
674 | |
675 class TypeInfo_Interface : TypeInfo | |
676 { | |
677 char[] toString() { return info.name; } | |
678 | |
679 int opEquals(Object o) | |
680 { TypeInfo_Interface c; | |
681 | |
682 return this is o || | |
683 ((c = cast(TypeInfo_Interface)o) !is null && | |
684 this.info.name == c.classinfo.name); | |
685 } | |
686 | |
687 hash_t getHash(void *p) | |
688 { | |
689 Interface* pi = **cast(Interface ***)*cast(void**)p; | |
690 Object o = cast(Object)(*cast(void**)p - pi.offset); | |
691 assert(o); | |
692 return o.toHash(); | |
693 } | |
694 | |
695 int equals(void *p1, void *p2) | |
696 { | |
697 Interface* pi = **cast(Interface ***)*cast(void**)p1; | |
698 Object o1 = cast(Object)(*cast(void**)p1 - pi.offset); | |
699 pi = **cast(Interface ***)*cast(void**)p2; | |
700 Object o2 = cast(Object)(*cast(void**)p2 - pi.offset); | |
701 | |
702 return o1 == o2 || (o1 && o1.opCmp(o2) == 0); | |
703 } | |
704 | |
705 int compare(void *p1, void *p2) | |
706 { | |
707 Interface* pi = **cast(Interface ***)*cast(void**)p1; | |
708 Object o1 = cast(Object)(*cast(void**)p1 - pi.offset); | |
709 pi = **cast(Interface ***)*cast(void**)p2; | |
710 Object o2 = cast(Object)(*cast(void**)p2 - pi.offset); | |
711 int c = 0; | |
712 | |
713 // Regard null references as always being "less than" | |
714 if (o1 != o2) | |
715 { | |
716 if (o1) | |
717 { if (!o2) | |
718 c = 1; | |
719 else | |
720 c = o1.opCmp(o2); | |
721 } | |
722 else | |
723 c = -1; | |
724 } | |
725 return c; | |
726 } | |
727 | |
728 size_t tsize() | |
729 { | |
730 return Object.sizeof; | |
731 } | |
732 | |
733 uint flags() { return 1; } | |
734 | |
735 ClassInfo info; | |
736 } | |
737 | |
738 class TypeInfo_Struct : TypeInfo | |
739 { | |
740 char[] toString() { return name; } | |
741 | |
742 int opEquals(Object o) | |
743 { TypeInfo_Struct s; | |
744 | |
745 return this is o || | |
746 ((s = cast(TypeInfo_Struct)o) !is null && | |
747 this.name == s.name && | |
748 this.init.length == s.init.length); | |
749 } | |
750 | |
751 hash_t getHash(void *p) | |
752 { hash_t h; | |
753 | |
754 assert(p); | |
755 if (xtoHash) | |
756 { debug(PRINTF) printf("getHash() using xtoHash\n"); | |
757 h = (*xtoHash)(p); | |
758 } | |
759 else | |
760 { | |
761 debug(PRINTF) printf("getHash() using default hash\n"); | |
762 // A sorry hash algorithm. | |
763 // Should use the one for strings. | |
764 // BUG: relies on the GC not moving objects | |
272
94ef6d63f7bb
[svn r293] Fixed: object.TypeInfo_Struct implementation was incorrect.
lindquist
parents:
271
diff
changeset
|
765 for (size_t i = 0; i < m_init.length; i++) |
132 | 766 { h = h * 9 + *cast(ubyte*)p; |
767 p++; | |
768 } | |
769 } | |
770 return h; | |
771 } | |
772 | |
272
94ef6d63f7bb
[svn r293] Fixed: object.TypeInfo_Struct implementation was incorrect.
lindquist
parents:
271
diff
changeset
|
773 int equals(void *p1, void *p2) |
132 | 774 { int c; |
775 | |
776 if (p1 == p2) | |
777 c = 1; | |
778 else if (!p1 || !p2) | |
779 c = 0; | |
780 else if (xopEquals) | |
781 c = (*xopEquals)(p1, p2); | |
782 else | |
783 // BUG: relies on the GC not moving objects | |
272
94ef6d63f7bb
[svn r293] Fixed: object.TypeInfo_Struct implementation was incorrect.
lindquist
parents:
271
diff
changeset
|
784 c = (memcmp(p1, p2, m_init.length) == 0); |
132 | 785 return c; |
786 } | |
787 | |
272
94ef6d63f7bb
[svn r293] Fixed: object.TypeInfo_Struct implementation was incorrect.
lindquist
parents:
271
diff
changeset
|
788 int compare(void *p1, void *p2) |
132 | 789 { |
790 int c = 0; | |
791 | |
792 // Regard null references as always being "less than" | |
793 if (p1 != p2) | |
794 { | |
795 if (p1) | |
796 { if (!p2) | |
797 c = 1; | |
798 else if (xopCmp) | |
799 c = (*xopCmp)(p1, p2); | |
800 else | |
801 // BUG: relies on the GC not moving objects | |
272
94ef6d63f7bb
[svn r293] Fixed: object.TypeInfo_Struct implementation was incorrect.
lindquist
parents:
271
diff
changeset
|
802 c = memcmp(p1, p2, m_init.length); |
132 | 803 } |
804 else | |
805 c = -1; | |
806 } | |
807 return c; | |
808 } | |
809 | |
810 size_t tsize() | |
811 { | |
272
94ef6d63f7bb
[svn r293] Fixed: object.TypeInfo_Struct implementation was incorrect.
lindquist
parents:
271
diff
changeset
|
812 return m_init.length; |
132 | 813 } |
814 | |
815 void[] init() { return m_init; } | |
816 | |
817 uint flags() { return m_flags; } | |
818 | |
819 char[] name; | |
272
94ef6d63f7bb
[svn r293] Fixed: object.TypeInfo_Struct implementation was incorrect.
lindquist
parents:
271
diff
changeset
|
820 void[] m_init; // initializer; never null |
132 | 821 |
822 hash_t function(void*) xtoHash; | |
823 int function(void*,void*) xopEquals; | |
824 int function(void*,void*) xopCmp; | |
825 char[] function(void*) xtoString; | |
826 | |
827 uint m_flags; | |
828 } | |
829 | |
830 class TypeInfo_Tuple : TypeInfo | |
831 { | |
832 TypeInfo[] elements; | |
833 | |
834 char[] toString() | |
835 { | |
836 char[] s; | |
837 s = "("; | |
838 foreach (i, element; elements) | |
839 { | |
840 if (i) | |
841 s ~= ','; | |
842 s ~= element.toString(); | |
843 } | |
844 s ~= ")"; | |
845 return s; | |
846 } | |
847 | |
848 int opEquals(Object o) | |
849 { | |
850 if (this is o) | |
851 return 1; | |
852 | |
853 auto t = cast(TypeInfo_Tuple)o; | |
854 if (t && elements.length == t.elements.length) | |
855 { | |
856 for (size_t i = 0; i < elements.length; i++) | |
857 { | |
858 if (elements[i] != t.elements[i]) | |
859 return 0; | |
860 } | |
861 return 1; | |
862 } | |
863 return 0; | |
864 } | |
865 | |
866 hash_t getHash(void *p) | |
867 { | |
868 assert(0); | |
869 } | |
870 | |
871 int equals(void *p1, void *p2) | |
872 { | |
873 assert(0); | |
874 } | |
875 | |
876 int compare(void *p1, void *p2) | |
877 { | |
878 assert(0); | |
879 } | |
880 | |
881 size_t tsize() | |
882 { | |
883 assert(0); | |
884 } | |
885 | |
886 void swap(void *p1, void *p2) | |
887 { | |
888 assert(0); | |
889 } | |
890 } | |
891 | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
892 |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
893 //////////////////////////////////////////////////////////////////////////////// |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
894 // Exception |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
895 //////////////////////////////////////////////////////////////////////////////// |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
896 |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
897 |
132 | 898 class Exception : Object |
899 { | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
900 interface TraceInfo |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
901 { |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
902 int opApply( int delegate( inout char[] ) ); |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
903 } |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
904 |
132 | 905 char[] msg; |
906 char[] file; | |
907 size_t line; | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
908 TraceInfo info; |
132 | 909 Exception next; |
910 | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
911 this( char[] msg, Exception next = null ) |
132 | 912 { |
913 this.msg = msg; | |
914 this.next = next; | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
915 this.info = traceContext(); |
132 | 916 } |
917 | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
918 this( char[] msg, char[] file, size_t line, Exception next = null ) |
132 | 919 { |
920 this(msg, next); | |
921 this.file = file; | |
922 this.line = line; | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
923 this.info = traceContext(); |
132 | 924 } |
925 | |
926 char[] toString() | |
927 { | |
928 return msg; | |
929 } | |
930 } | |
931 | |
932 | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
933 alias Exception.TraceInfo function( void* ptr = null ) TraceHandler; |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
934 private TraceHandler traceHandler = null; |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
935 |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
936 |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
937 /** |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
938 * Overrides the default trace hander with a user-supplied version. |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
939 * |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
940 * Params: |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
941 * h = The new trace handler. Set to null to use the default handler. |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
942 */ |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
943 extern (C) void rt_setTraceHandler( TraceHandler h ) |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
944 { |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
945 traceHandler = h; |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
946 } |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
947 |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
948 |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
949 /** |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
950 * This function will be called when an Exception is constructed. The |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
951 * user-supplied trace handler will be called if one has been supplied, |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
952 * otherwise no trace will be generated. |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
953 * |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
954 * Params: |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
955 * ptr = A pointer to the location from which to generate the trace, or null |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
956 * if the trace should be generated from within the trace handler |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
957 * itself. |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
958 * |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
959 * Returns: |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
960 * An object describing the current calling context or null if no handler is |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
961 * supplied. |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
962 */ |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
963 Exception.TraceInfo traceContext( void* ptr = null ) |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
964 { |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
965 if( traceHandler is null ) |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
966 return null; |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
967 return traceHandler( ptr ); |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
968 } |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
969 |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
970 |
132 | 971 //////////////////////////////////////////////////////////////////////////////// |
972 // ModuleInfo | |
973 //////////////////////////////////////////////////////////////////////////////// | |
974 | |
975 | |
976 enum | |
977 { | |
978 MIctorstart = 1, // we've started constructing it | |
979 MIctordone = 2, // finished construction | |
980 MIstandalone = 4, // module ctor does not depend on other module | |
981 // ctors being done first | |
982 MIhasictor = 8, // has ictor member | |
983 } | |
984 | |
985 | |
986 class ModuleInfo | |
987 { | |
988 char[] name; | |
989 ModuleInfo[] importedModules; | |
990 ClassInfo[] localClasses; | |
991 uint flags; | |
992 | |
993 void function() ctor; // module static constructor (order dependent) | |
994 void function() dtor; // module static destructor | |
995 void function() unitTest; // module unit tests | |
996 | |
997 void* xgetMembers; // module getMembers() function | |
998 | |
999 void function() ictor; // module static constructor (order independent) | |
1000 | |
1001 static int opApply( int delegate( inout ModuleInfo ) dg ) | |
1002 { | |
1003 int ret = 0; | |
1004 | |
1005 foreach( m; _moduleinfo_array ) | |
1006 { | |
1007 ret = dg( m ); | |
1008 if( ret ) | |
1009 break; | |
1010 } | |
1011 return ret; | |
1012 } | |
1013 } | |
1014 | |
1015 | |
323
0d52412d5b1a
[svn r344] Fixed some very minor issues with the usage listing when calling llvmdc with no arguments.
lindquist
parents:
275
diff
changeset
|
1016 // this gets initialized in _moduleCtor() |
132 | 1017 extern (C) ModuleInfo[] _moduleinfo_array; |
1018 | |
323
0d52412d5b1a
[svn r344] Fixed some very minor issues with the usage listing when calling llvmdc with no arguments.
lindquist
parents:
275
diff
changeset
|
1019 // This linked list is created by a compiler generated function inserted |
0d52412d5b1a
[svn r344] Fixed some very minor issues with the usage listing when calling llvmdc with no arguments.
lindquist
parents:
275
diff
changeset
|
1020 // into the .ctor list by the compiler. |
0d52412d5b1a
[svn r344] Fixed some very minor issues with the usage listing when calling llvmdc with no arguments.
lindquist
parents:
275
diff
changeset
|
1021 struct ModuleReference |
0d52412d5b1a
[svn r344] Fixed some very minor issues with the usage listing when calling llvmdc with no arguments.
lindquist
parents:
275
diff
changeset
|
1022 { |
0d52412d5b1a
[svn r344] Fixed some very minor issues with the usage listing when calling llvmdc with no arguments.
lindquist
parents:
275
diff
changeset
|
1023 ModuleReference* next; |
0d52412d5b1a
[svn r344] Fixed some very minor issues with the usage listing when calling llvmdc with no arguments.
lindquist
parents:
275
diff
changeset
|
1024 ModuleInfo mod; |
0d52412d5b1a
[svn r344] Fixed some very minor issues with the usage listing when calling llvmdc with no arguments.
lindquist
parents:
275
diff
changeset
|
1025 } |
0d52412d5b1a
[svn r344] Fixed some very minor issues with the usage listing when calling llvmdc with no arguments.
lindquist
parents:
275
diff
changeset
|
1026 extern (C) ModuleReference* _Dmodule_ref; // start of linked list |
132 | 1027 |
323
0d52412d5b1a
[svn r344] Fixed some very minor issues with the usage listing when calling llvmdc with no arguments.
lindquist
parents:
275
diff
changeset
|
1028 // this list is built from the linked list above |
132 | 1029 ModuleInfo[] _moduleinfo_dtors; |
1030 uint _moduleinfo_dtors_i; | |
1031 | |
1032 /** | |
1033 * Initialize the modules. | |
1034 */ | |
1035 | |
1036 extern (C) void _moduleCtor() | |
1037 { | |
1038 debug(PRINTF) printf("_moduleCtor()\n"); | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1039 |
323
0d52412d5b1a
[svn r344] Fixed some very minor issues with the usage listing when calling llvmdc with no arguments.
lindquist
parents:
275
diff
changeset
|
1040 int len = 0; |
0d52412d5b1a
[svn r344] Fixed some very minor issues with the usage listing when calling llvmdc with no arguments.
lindquist
parents:
275
diff
changeset
|
1041 ModuleReference *mr; |
132 | 1042 |
323
0d52412d5b1a
[svn r344] Fixed some very minor issues with the usage listing when calling llvmdc with no arguments.
lindquist
parents:
275
diff
changeset
|
1043 for (mr = _Dmodule_ref; mr; mr = mr.next) |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1044 len++; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1045 _moduleinfo_array = new ModuleInfo[len]; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1046 len = 0; |
323
0d52412d5b1a
[svn r344] Fixed some very minor issues with the usage listing when calling llvmdc with no arguments.
lindquist
parents:
275
diff
changeset
|
1047 for (mr = _Dmodule_ref; mr; mr = mr.next) |
0d52412d5b1a
[svn r344] Fixed some very minor issues with the usage listing when calling llvmdc with no arguments.
lindquist
parents:
275
diff
changeset
|
1048 { _moduleinfo_array[len] = mr.mod; |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1049 len++; |
132 | 1050 } |
1051 | |
1052 _moduleinfo_dtors = new ModuleInfo[_moduleinfo_array.length]; | |
1053 debug(PRINTF) printf("_moduleinfo_dtors = x%x\n", cast(void *)_moduleinfo_dtors); | |
1054 _moduleIndependentCtors(); | |
1055 _moduleCtor2(_moduleinfo_array, 0); | |
1056 } | |
1057 | |
1058 extern (C) void _moduleIndependentCtors() | |
1059 { | |
1060 debug(PRINTF) printf("_moduleIndependentCtors()\n"); | |
1061 foreach (m; _moduleinfo_array) | |
1062 { | |
1063 if (m && m.flags & MIhasictor && m.ictor) | |
1064 { | |
1065 (*m.ictor)(); | |
1066 } | |
1067 } | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1068 debug(PRINTF) printf("_moduleIndependentCtors() DONE\n"); |
132 | 1069 } |
1070 | |
1071 void _moduleCtor2(ModuleInfo[] mi, int skip) | |
1072 { | |
1073 debug(PRINTF) printf("_moduleCtor2(): %d modules\n", mi.length); | |
1074 for (uint i = 0; i < mi.length; i++) | |
1075 { | |
1076 ModuleInfo m = mi[i]; | |
1077 | |
1078 debug(PRINTF) printf("\tmodule[%d] = '%p'\n", i, m); | |
1079 if (!m) | |
1080 continue; | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1081 debug(PRINTF) printf("\tmodule[%d] = '%.*s'\n", i, m.name.length, m.name.ptr); |
132 | 1082 if (m.flags & MIctordone) |
1083 continue; | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1084 debug(PRINTF) printf("\tmodule[%d] = '%.*s', m = x%x\n", i, m.name.length, m.name.ptr, m); |
132 | 1085 |
1086 if (m.ctor || m.dtor) | |
1087 { | |
1088 if (m.flags & MIctorstart) | |
1089 { if (skip || m.flags & MIstandalone) | |
1090 continue; | |
1091 throw new Exception( "Cyclic dependency in module " ~ m.name ); | |
1092 } | |
1093 | |
1094 m.flags |= MIctorstart; | |
1095 _moduleCtor2(m.importedModules, 0); | |
1096 if (m.ctor) | |
1097 (*m.ctor)(); | |
1098 m.flags &= ~MIctorstart; | |
1099 m.flags |= MIctordone; | |
1100 | |
1101 // Now that construction is done, register the destructor | |
1102 //printf("\tadding module dtor x%x\n", m); | |
1103 assert(_moduleinfo_dtors_i < _moduleinfo_dtors.length); | |
1104 _moduleinfo_dtors[_moduleinfo_dtors_i++] = m; | |
1105 } | |
1106 else | |
1107 { | |
1108 m.flags |= MIctordone; | |
1109 _moduleCtor2(m.importedModules, 1); | |
1110 } | |
1111 } | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1112 debug(PRINTF) printf("_moduleCtor2() DONE\n"); |
132 | 1113 } |
1114 | |
1115 /** | |
1116 * Destruct the modules. | |
1117 */ | |
1118 | |
1119 // Starting the name with "_STD" means under linux a pointer to the | |
1120 // function gets put in the .dtors segment. | |
1121 | |
1122 extern (C) void _moduleDtor() | |
1123 { | |
1124 debug(PRINTF) printf("_moduleDtor(): %d modules\n", _moduleinfo_dtors_i); | |
1125 | |
1126 for (uint i = _moduleinfo_dtors_i; i-- != 0;) | |
1127 { | |
1128 ModuleInfo m = _moduleinfo_dtors[i]; | |
1129 | |
1130 debug(PRINTF) printf("\tmodule[%d] = '%.*s', x%x\n", i, m.name, m); | |
1131 if (m.dtor) | |
1132 { | |
1133 (*m.dtor)(); | |
1134 } | |
1135 } | |
1136 debug(PRINTF) printf("_moduleDtor() done\n"); | |
1137 } | |
1138 | |
1139 //////////////////////////////////////////////////////////////////////////////// | |
1140 // Monitor | |
1141 //////////////////////////////////////////////////////////////////////////////// | |
1142 | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1143 alias Object.Monitor IMonitor; |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1144 alias void delegate(Object) DEvent; |
132 | 1145 |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1146 // NOTE: The dtor callback feature is only supported for monitors that are not |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1147 // supplied by the user. The assumption is that any object with a user- |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1148 // supplied monitor may have special storage or lifetime requirements and |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1149 // that as a result, storing references to local objects within Monitor |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1150 // may not be safe or desirable. Thus, devt is only valid if impl is |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1151 // null. |
132 | 1152 struct Monitor |
1153 { | |
1154 IMonitor impl; | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1155 /* internal */ |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1156 DEvent[] devt; |
132 | 1157 /* stuff */ |
1158 } | |
1159 | |
1160 Monitor* getMonitor(Object h) | |
1161 { | |
1162 return cast(Monitor*) (cast(void**) h)[1]; | |
1163 } | |
1164 | |
1165 void setMonitor(Object h, Monitor* m) | |
1166 { | |
1167 (cast(void**) h)[1] = m; | |
1168 } | |
1169 | |
1170 extern (C) void _d_monitor_create(Object); | |
1171 extern (C) void _d_monitor_destroy(Object); | |
1172 extern (C) void _d_monitor_lock(Object); | |
1173 extern (C) int _d_monitor_unlock(Object); | |
1174 | |
1175 extern (C) void _d_monitordelete(Object h, bool det) | |
1176 { | |
1177 Monitor* m = getMonitor(h); | |
1178 | |
1179 if (m !is null) | |
1180 { | |
1181 IMonitor i = m.impl; | |
1182 if (i is null) | |
1183 { | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1184 _d_monitor_devt(m, h); |
132 | 1185 _d_monitor_destroy(h); |
1186 setMonitor(h, null); | |
1187 return; | |
1188 } | |
1189 if (det && (cast(void*) i) !is (cast(void*) h)) | |
1190 delete i; | |
1191 setMonitor(h, null); | |
1192 } | |
1193 } | |
1194 | |
1195 extern (C) void _d_monitorenter(Object h) | |
1196 { | |
1197 Monitor* m = getMonitor(h); | |
1198 | |
1199 if (m is null) | |
1200 { | |
1201 _d_monitor_create(h); | |
1202 m = getMonitor(h); | |
1203 } | |
1204 | |
1205 IMonitor i = m.impl; | |
1206 | |
1207 if (i is null) | |
1208 { | |
1209 _d_monitor_lock(h); | |
1210 return; | |
1211 } | |
1212 i.lock(); | |
1213 } | |
1214 | |
1215 extern (C) void _d_monitorexit(Object h) | |
1216 { | |
1217 Monitor* m = getMonitor(h); | |
1218 IMonitor i = m.impl; | |
1219 | |
1220 if (i is null) | |
1221 { | |
1222 _d_monitor_unlock(h); | |
1223 return; | |
1224 } | |
1225 i.unlock(); | |
1226 } | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1227 |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1228 extern (C) void _d_monitor_devt(Monitor* m, Object h) |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1229 { |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1230 if (m.devt.length) |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1231 { |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1232 DEvent[] devt; |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1233 |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1234 synchronized (h) |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1235 { |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1236 devt = m.devt; |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1237 m.devt = null; |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1238 } |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1239 foreach (v; devt) |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1240 { |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1241 if (v) |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1242 v(h); |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1243 } |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1244 free(devt.ptr); |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1245 } |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1246 } |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1247 |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1248 extern (C) void rt_attachDisposeEvent(Object h, DEvent e) |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1249 { |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1250 synchronized (h) |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1251 { |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1252 Monitor* m = getMonitor(h); |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1253 assert(m.impl is null); |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1254 |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1255 foreach (inout v; m.devt) |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1256 { |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1257 if (v is null || v == e) |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1258 { |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1259 v = e; |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1260 return; |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1261 } |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1262 } |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1263 |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1264 auto len = m.devt.length + 4; // grow by 4 elements |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1265 auto pos = m.devt.length; // insert position |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1266 auto p = realloc(m.devt.ptr, DEvent.sizeof * len); |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1267 if (!p) |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1268 onOutOfMemoryError(); |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1269 m.devt = (cast(DEvent*)p)[0 .. len]; |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1270 m.devt[pos+1 .. len] = null; |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1271 m.devt[pos] = e; |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1272 } |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1273 } |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1274 |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1275 extern (C) void rt_detachDisposeEvent(Object h, DEvent e) |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1276 { |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1277 synchronized (h) |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1278 { |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1279 Monitor* m = getMonitor(h); |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1280 assert(m.impl is null); |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1281 |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1282 foreach (p, v; m.devt) |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1283 { |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1284 if (v == e) |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1285 { |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1286 memmove(&m.devt[p], |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1287 &m.devt[p+1], |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1288 (m.devt.length - p - 1) * DEvent.sizeof); |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1289 m.devt[$ - 1] = null; |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1290 return; |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1291 } |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1292 } |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1293 } |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1294 } |