Mercurial > projects > ldc
annotate tango/lib/compiler/llvmdc/genobj.d @ 275:665b81613475 trunk
[svn r296] Removed: the 'suite' dir, it never took off!
Fixed: foreach statement, key-type checks were buggy.
Fixed: setting LLVMDC versions on the command line is now an error.
Fixed: array compare runtime had incorrect param attrs on call.
Fixed: index expressions on dynamic array slices w/o storage was broken.
Fixed: scope classes had incorrect finalization in some cases.
Fixed: when outputting !ClassInfoS !OffsetTypeInfoS, static class members were trying to be included, crashing the compiler.
Fixed: calling LLVMDC with -inline but not any -O option caused assertion failure.
Changed: the runtime now uses a single interface to "get" to !TypeInfoS, part of eliminating duplicate !TypeInfo codegen.
author | lindquist |
---|---|
date | Thu, 19 Jun 2008 17:30:32 +0200 |
parents | 94ef6d63f7bb |
children | 0d52412d5b1a |
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 | |
1016 // Win32: this gets initialized by minit.asm | |
1017 // linux: this gets initialized in _moduleCtor() | |
1018 extern (C) ModuleInfo[] _moduleinfo_array; | |
1019 | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1020 // llvmdc method |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1021 extern (C) void** _d_get_moduleinfo_array(); |
132 | 1022 |
1023 ModuleInfo[] _moduleinfo_dtors; | |
1024 uint _moduleinfo_dtors_i; | |
1025 | |
1026 // Register termination function pointers | |
1027 extern (C) int _fatexit(void *); | |
1028 | |
1029 /** | |
1030 * Initialize the modules. | |
1031 */ | |
1032 | |
1033 extern (C) void _moduleCtor() | |
1034 { | |
1035 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
|
1036 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1037 ModuleInfo* mrbegin = cast(ModuleInfo*)_d_get_moduleinfo_array(); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1038 assert(mrbegin !is null); |
132 | 1039 |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1040 int len = 0; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1041 ModuleInfo* mr; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1042 for (mr = mrbegin; *mr !is null; ++mr) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1043 len++; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1044 _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
|
1045 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1046 len = 0; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1047 for (mr = mrbegin; *mr !is null; ++mr) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1048 { _moduleinfo_array[len] = *mr; |
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 version (Win32) | |
1053 { | |
1054 // Ensure module destructors also get called on program termination | |
1055 //_fatexit(&_STD_moduleDtor); | |
1056 } | |
1057 | |
1058 _moduleinfo_dtors = new ModuleInfo[_moduleinfo_array.length]; | |
1059 debug(PRINTF) printf("_moduleinfo_dtors = x%x\n", cast(void *)_moduleinfo_dtors); | |
1060 _moduleIndependentCtors(); | |
1061 _moduleCtor2(_moduleinfo_array, 0); | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1062 debug(PRINTF) printf("_moduleCtor() DONE\n"); |
132 | 1063 } |
1064 | |
1065 extern (C) void _moduleIndependentCtors() | |
1066 { | |
1067 debug(PRINTF) printf("_moduleIndependentCtors()\n"); | |
1068 foreach (m; _moduleinfo_array) | |
1069 { | |
1070 if (m && m.flags & MIhasictor && m.ictor) | |
1071 { | |
1072 (*m.ictor)(); | |
1073 } | |
1074 } | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1075 debug(PRINTF) printf("_moduleIndependentCtors() DONE\n"); |
132 | 1076 } |
1077 | |
1078 void _moduleCtor2(ModuleInfo[] mi, int skip) | |
1079 { | |
1080 debug(PRINTF) printf("_moduleCtor2(): %d modules\n", mi.length); | |
1081 for (uint i = 0; i < mi.length; i++) | |
1082 { | |
1083 ModuleInfo m = mi[i]; | |
1084 | |
1085 debug(PRINTF) printf("\tmodule[%d] = '%p'\n", i, m); | |
1086 if (!m) | |
1087 continue; | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1088 debug(PRINTF) printf("\tmodule[%d] = '%.*s'\n", i, m.name.length, m.name.ptr); |
132 | 1089 if (m.flags & MIctordone) |
1090 continue; | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1091 debug(PRINTF) printf("\tmodule[%d] = '%.*s', m = x%x\n", i, m.name.length, m.name.ptr, m); |
132 | 1092 |
1093 if (m.ctor || m.dtor) | |
1094 { | |
1095 if (m.flags & MIctorstart) | |
1096 { if (skip || m.flags & MIstandalone) | |
1097 continue; | |
1098 throw new Exception( "Cyclic dependency in module " ~ m.name ); | |
1099 } | |
1100 | |
1101 m.flags |= MIctorstart; | |
1102 _moduleCtor2(m.importedModules, 0); | |
1103 if (m.ctor) | |
1104 (*m.ctor)(); | |
1105 m.flags &= ~MIctorstart; | |
1106 m.flags |= MIctordone; | |
1107 | |
1108 // Now that construction is done, register the destructor | |
1109 //printf("\tadding module dtor x%x\n", m); | |
1110 assert(_moduleinfo_dtors_i < _moduleinfo_dtors.length); | |
1111 _moduleinfo_dtors[_moduleinfo_dtors_i++] = m; | |
1112 } | |
1113 else | |
1114 { | |
1115 m.flags |= MIctordone; | |
1116 _moduleCtor2(m.importedModules, 1); | |
1117 } | |
1118 } | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1119 debug(PRINTF) printf("_moduleCtor2() DONE\n"); |
132 | 1120 } |
1121 | |
1122 /** | |
1123 * Destruct the modules. | |
1124 */ | |
1125 | |
1126 // Starting the name with "_STD" means under linux a pointer to the | |
1127 // function gets put in the .dtors segment. | |
1128 | |
1129 extern (C) void _moduleDtor() | |
1130 { | |
1131 debug(PRINTF) printf("_moduleDtor(): %d modules\n", _moduleinfo_dtors_i); | |
1132 | |
1133 for (uint i = _moduleinfo_dtors_i; i-- != 0;) | |
1134 { | |
1135 ModuleInfo m = _moduleinfo_dtors[i]; | |
1136 | |
1137 debug(PRINTF) printf("\tmodule[%d] = '%.*s', x%x\n", i, m.name, m); | |
1138 if (m.dtor) | |
1139 { | |
1140 (*m.dtor)(); | |
1141 } | |
1142 } | |
1143 debug(PRINTF) printf("_moduleDtor() done\n"); | |
1144 } | |
1145 | |
1146 //////////////////////////////////////////////////////////////////////////////// | |
1147 // Monitor | |
1148 //////////////////////////////////////////////////////////////////////////////// | |
1149 | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1150 alias Object.Monitor IMonitor; |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1151 alias void delegate(Object) DEvent; |
132 | 1152 |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1153 // 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
|
1154 // 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
|
1155 // 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
|
1156 // 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
|
1157 // 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
|
1158 // null. |
132 | 1159 struct Monitor |
1160 { | |
1161 IMonitor impl; | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1162 /* internal */ |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1163 DEvent[] devt; |
132 | 1164 /* stuff */ |
1165 } | |
1166 | |
1167 Monitor* getMonitor(Object h) | |
1168 { | |
1169 return cast(Monitor*) (cast(void**) h)[1]; | |
1170 } | |
1171 | |
1172 void setMonitor(Object h, Monitor* m) | |
1173 { | |
1174 (cast(void**) h)[1] = m; | |
1175 } | |
1176 | |
1177 extern (C) void _d_monitor_create(Object); | |
1178 extern (C) void _d_monitor_destroy(Object); | |
1179 extern (C) void _d_monitor_lock(Object); | |
1180 extern (C) int _d_monitor_unlock(Object); | |
1181 | |
1182 extern (C) void _d_monitordelete(Object h, bool det) | |
1183 { | |
1184 Monitor* m = getMonitor(h); | |
1185 | |
1186 if (m !is null) | |
1187 { | |
1188 IMonitor i = m.impl; | |
1189 if (i is null) | |
1190 { | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1191 _d_monitor_devt(m, h); |
132 | 1192 _d_monitor_destroy(h); |
1193 setMonitor(h, null); | |
1194 return; | |
1195 } | |
1196 if (det && (cast(void*) i) !is (cast(void*) h)) | |
1197 delete i; | |
1198 setMonitor(h, null); | |
1199 } | |
1200 } | |
1201 | |
1202 extern (C) void _d_monitorenter(Object h) | |
1203 { | |
1204 Monitor* m = getMonitor(h); | |
1205 | |
1206 if (m is null) | |
1207 { | |
1208 _d_monitor_create(h); | |
1209 m = getMonitor(h); | |
1210 } | |
1211 | |
1212 IMonitor i = m.impl; | |
1213 | |
1214 if (i is null) | |
1215 { | |
1216 _d_monitor_lock(h); | |
1217 return; | |
1218 } | |
1219 i.lock(); | |
1220 } | |
1221 | |
1222 extern (C) void _d_monitorexit(Object h) | |
1223 { | |
1224 Monitor* m = getMonitor(h); | |
1225 IMonitor i = m.impl; | |
1226 | |
1227 if (i is null) | |
1228 { | |
1229 _d_monitor_unlock(h); | |
1230 return; | |
1231 } | |
1232 i.unlock(); | |
1233 } | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1234 |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1235 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
|
1236 { |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1237 if (m.devt.length) |
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 DEvent[] 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 synchronized (h) |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1242 { |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1243 devt = m.devt; |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1244 m.devt = null; |
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 foreach (v; devt) |
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 if (v) |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1249 v(h); |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1250 } |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1251 free(devt.ptr); |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1252 } |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1253 } |
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 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
|
1256 { |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1257 synchronized (h) |
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 Monitor* m = getMonitor(h); |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1260 assert(m.impl is null); |
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 foreach (inout v; m.devt) |
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 if (v is null || v == e) |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1265 { |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1266 v = e; |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1267 return; |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1268 } |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1269 } |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1270 |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1271 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
|
1272 auto pos = m.devt.length; // insert position |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1273 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
|
1274 if (!p) |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1275 onOutOfMemoryError(); |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1276 m.devt = (cast(DEvent*)p)[0 .. len]; |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1277 m.devt[pos+1 .. len] = null; |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1278 m.devt[pos] = e; |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1279 } |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1280 } |
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 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
|
1283 { |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1284 synchronized (h) |
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 Monitor* m = getMonitor(h); |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1287 assert(m.impl is null); |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1288 |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1289 foreach (p, v; m.devt) |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1290 { |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1291 if (v == e) |
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 memmove(&m.devt[p], |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1294 &m.devt[p+1], |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1295 (m.devt.length - p - 1) * DEvent.sizeof); |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1296 m.devt[$ - 1] = null; |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1297 return; |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1298 } |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1299 } |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1300 } |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
133
diff
changeset
|
1301 } |