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