Mercurial > projects > ldc
comparison lphobos/internal/objectimpl.d @ 52:0c77619e803b trunk
[svn r56] Initial support for TypeInfo.
Enums not work.
Several other bugfixes.
author | lindquist |
---|---|
date | Tue, 23 Oct 2007 05:55:12 +0200 |
parents | 0b9b286b67b6 |
children | 28e99b04a132 |
comparison
equal
deleted
inserted
replaced
51:61bc1b4ad3c4 | 52:0c77619e803b |
---|---|
35 | 35 |
36 module object; | 36 module object; |
37 | 37 |
38 //import std.outofmemory; | 38 //import std.outofmemory; |
39 | 39 |
40 /** | |
41 * An unsigned integral type large enough to span the memory space. Use for | |
42 * array indices and pointer offsets for maximal portability to | |
43 * architectures that have different memory address ranges. This is | |
44 * analogous to C's size_t. | |
45 */ | |
46 alias typeof(int.sizeof) size_t; | |
47 | |
48 /** | |
49 * A signed integral type large enough to span the memory space. Use for | |
50 * pointer differences and for size_t differences for maximal portability to | |
51 * architectures that have different memory address ranges. This is | |
52 * analogous to C's ptrdiff_t. | |
53 */ | |
54 alias typeof(cast(void*)0 - cast(void*)0) ptrdiff_t; | |
55 | |
56 alias size_t hash_t; | |
57 | |
40 extern (C) | 58 extern (C) |
41 { /// C's printf function. | 59 { /// C's printf function. |
42 int printf(char *, ...); | 60 int printf(char *, ...); |
61 void trace_term(); | |
43 | 62 |
44 int memcmp(void *, void *, size_t); | 63 int memcmp(void *, void *, size_t); |
45 void* memcpy(void *, void *, size_t); | 64 void* memcpy(void *, void *, size_t); |
46 void* calloc(size_t, size_t); | 65 void* calloc(size_t, size_t); |
47 void* realloc(void*, size_t); | 66 void* realloc(void*, size_t); |
51 } | 70 } |
52 | 71 |
53 /// Standard boolean type. | 72 /// Standard boolean type. |
54 alias bool bit; | 73 alias bool bit; |
55 | 74 |
56 version (LLVM64) | 75 alias char[] string; |
57 { | 76 alias wchar[] wstring; |
58 /** | 77 alias dchar[] dstring; |
59 * An unsigned integral type large enough to span the memory space. Use for | |
60 * array indices and pointer offsets for maximal portability to | |
61 * architectures that have different memory address ranges. This is | |
62 * analogous to C's size_t. | |
63 */ | |
64 alias ulong size_t; | |
65 | |
66 /** | |
67 * A signed integral type large enough to span the memory space. Use for | |
68 * pointer differences and for size_t differences for maximal portability to | |
69 * architectures that have different memory address ranges. This is | |
70 * analogous to C's ptrdiff_t. | |
71 */ | |
72 alias long ptrdiff_t; | |
73 | |
74 alias ulong hash_t; | |
75 } | |
76 else | |
77 { | |
78 alias uint size_t; | |
79 alias int ptrdiff_t; | |
80 alias uint hash_t; | |
81 } | |
82 | 78 |
83 /+ | 79 /+ |
80 | |
84 /* ************************* | 81 /* ************************* |
85 * Internal struct pointed to by the hidden .monitor member. | 82 * Internal struct pointed to by the hidden .monitor member. |
86 */ | 83 */ |
87 struct Monitor | 84 struct Monitor |
88 { | 85 { |
89 void delegate(Object)[] delegates; | 86 void delegate(Object)[] delegates; |
90 | 87 |
91 /* More stuff goes here defined by internal/monitor.c */ | 88 /* More stuff goes here defined by internal/monitor.c */ |
92 } | 89 } |
90 | |
93 +/ | 91 +/ |
94 | 92 |
95 /****************** | 93 /****************** |
96 * All D class objects inherit from Object. | 94 * All D class objects inherit from Object. |
97 */ | 95 */ |
107 * Convert Object to a human readable string. | 105 * Convert Object to a human readable string. |
108 */ | 106 */ |
109 char[] toString() | 107 char[] toString() |
110 { | 108 { |
111 //return this.classinfo.name; | 109 //return this.classinfo.name; |
112 return "Object.toString: classinfo not yet implemented"; | 110 return "object.Object (no classinfo yet)"; |
113 } | 111 } |
114 | 112 |
115 /** | 113 /** |
116 * Compute hash function for Object. | 114 * Compute hash function for Object. |
117 */ | 115 */ |
118 hash_t toHash() | 116 hash_t toHash() |
119 { | 117 { |
120 // BUG: this prevents a compacting GC from working, needs to be fixed | 118 // BUG: this prevents a compacting GC from working, needs to be fixed |
121 return cast(uint)cast(void *)this; | 119 return cast(hash_t)cast(void *)this; |
122 } | 120 } |
123 | 121 |
124 /** | 122 /** |
125 * Compare with another Object obj. | 123 * Compare with another Object obj. |
126 * Returns: | 124 * Returns: |
133 int opCmp(Object o) | 131 int opCmp(Object o) |
134 { | 132 { |
135 // BUG: this prevents a compacting GC from working, needs to be fixed | 133 // BUG: this prevents a compacting GC from working, needs to be fixed |
136 //return cast(int)cast(void *)this - cast(int)cast(void *)o; | 134 //return cast(int)cast(void *)this - cast(int)cast(void *)o; |
137 | 135 |
138 assert(0, "need opCmp for class <no classinfo yet>"); | |
139 //throw new Error("need opCmp for class " ~ this.classinfo.name); | 136 //throw new Error("need opCmp for class " ~ this.classinfo.name); |
137 throw new Error("need opCmp for class unknown object.Object (no classinfo yet)"); | |
140 } | 138 } |
141 | 139 |
142 /** | 140 /** |
143 * Returns !=0 if this object does have the same contents as obj. | 141 * Returns !=0 if this object does have the same contents as obj. |
144 */ | 142 */ |
156 * This is only for use by library developers, as it will need to be | 154 * This is only for use by library developers, as it will need to be |
157 * redone if weak pointers are added or a moving gc is developed. | 155 * redone if weak pointers are added or a moving gc is developed. |
158 */ | 156 */ |
159 final void notifyRegister(void delegate(Object) dg) | 157 final void notifyRegister(void delegate(Object) dg) |
160 { | 158 { |
159 /+ | |
161 //printf("notifyRegister(dg = %llx, o = %p)\n", dg, this); | 160 //printf("notifyRegister(dg = %llx, o = %p)\n", dg, this); |
162 /+synchronized (this) | 161 synchronized (this) |
163 { | 162 { |
164 Monitor* m = cast(Monitor*)(cast(void**)this)[1]; | 163 Monitor* m = cast(Monitor*)(cast(void**)this)[1]; |
165 foreach (inout x; m.delegates) | 164 foreach (inout x; m.delegates) |
166 { | 165 { |
167 if (!x || x == dg) | 166 if (!x || x == dg) |
189 _d_OutOfMemory(); | 188 _d_OutOfMemory(); |
190 m.delegates = (cast(void delegate(Object)*)p)[0 .. len]; | 189 m.delegates = (cast(void delegate(Object)*)p)[0 .. len]; |
191 m.delegates[startlen .. len] = null; | 190 m.delegates[startlen .. len] = null; |
192 } | 191 } |
193 m.delegates[startlen] = dg; | 192 m.delegates[startlen] = dg; |
194 }+/ | 193 } |
194 +/ | |
195 } | 195 } |
196 | 196 |
197 /* ** | 197 /* ** |
198 * Remove delegate dg from the notify list. | 198 * Remove delegate dg from the notify list. |
199 * This is only for use by library developers, as it will need to be | 199 * This is only for use by library developers, as it will need to be |
200 * redone if weak pointers are added or a moving gc is developed. | 200 * redone if weak pointers are added or a moving gc is developed. |
201 */ | 201 */ |
202 final void notifyUnRegister(void delegate(Object) dg) | 202 final void notifyUnRegister(void delegate(Object) dg) |
203 { | 203 { |
204 /+synchronized (this) | 204 /+ |
205 synchronized (this) | |
205 { | 206 { |
206 Monitor* m = cast(Monitor*)(cast(void**)this)[1]; | 207 Monitor* m = cast(Monitor*)(cast(void**)this)[1]; |
207 foreach (inout x; m.delegates) | 208 foreach (inout x; m.delegates) |
208 { | 209 { |
209 if (x == dg) | 210 if (x == dg) |
210 x = null; | 211 x = null; |
211 } | 212 } |
212 }+/ | 213 } |
214 +/ | |
213 } | 215 } |
214 | 216 |
215 /****** | 217 /****** |
216 * Create instance of class specified by classname. | 218 * Create instance of class specified by classname. |
217 * The class must either have no constructors or have | 219 * The class must either have no constructors or have |
218 * a default constructor. | 220 * a default constructor. |
219 * Returns: | 221 * Returns: |
220 * null if failed | 222 * null if failed |
221 */ | 223 */ |
222 /+static Object factory(char[] classname) | 224 static Object factory(char[] classname) |
223 { | 225 { |
226 /+ | |
224 auto ci = ClassInfo.find(classname); | 227 auto ci = ClassInfo.find(classname); |
225 if (ci) | 228 if (ci) |
226 { | 229 { |
227 return ci.create(); | 230 return ci.create(); |
228 } | 231 } |
232 +/ | |
229 return null; | 233 return null; |
230 }+/ | 234 } |
231 } | 235 } |
232 | 236 |
233 /+ | 237 /+ |
234 extern (C) void _d_notify_release(Object o) | 238 extern (C) void _d_notify_release(Object o) |
235 { | 239 { |
328 } | 332 } |
329 } | 333 } |
330 | 334 |
331 private import std.string; | 335 private import std.string; |
332 | 336 |
337 +/ | |
338 | |
333 /** | 339 /** |
334 * Array of pairs giving the offset and type information for each | 340 * Array of pairs giving the offset and type information for each |
335 * member in an aggregate. | 341 * member in an aggregate. |
336 */ | 342 */ |
337 struct OffsetTypeInfo | 343 struct OffsetTypeInfo |
338 { | 344 { |
339 size_t offset; /// Offset of member from start of object | 345 size_t offset; /// Offset of member from start of object |
340 TypeInfo ti; /// TypeInfo for this member | 346 TypeInfo ti; /// TypeInfo for this member |
347 } | |
348 | |
349 private int string_cmp(char[] s1, char[] s2) | |
350 { | |
351 auto len = s1.length; | |
352 if (s2.length < len) | |
353 len = s2.length; | |
354 int result = memcmp(s1.ptr, s2.ptr, len); | |
355 if (result == 0) | |
356 result = cast(int)(cast(ptrdiff_t)s1.length - cast(ptrdiff_t)s2.length); | |
357 return result; | |
341 } | 358 } |
342 | 359 |
343 /** | 360 /** |
344 * Runtime type information about a type. | 361 * Runtime type information about a type. |
345 * Can be retrieved for any type using a | 362 * Can be retrieved for any type using a |
360 if (this is o) | 377 if (this is o) |
361 return 0; | 378 return 0; |
362 TypeInfo ti = cast(TypeInfo)o; | 379 TypeInfo ti = cast(TypeInfo)o; |
363 if (ti is null) | 380 if (ti is null) |
364 return 1; | 381 return 1; |
365 return std.string.cmp(this.toString(), ti.toString()); | 382 return string_cmp(this.toString(), ti.toString()); |
366 } | 383 } |
367 | 384 |
368 int opEquals(Object o) | 385 int opEquals(Object o) |
369 { | 386 { |
370 /* TypeInfo instances are singletons, but duplicates can exist | 387 /* TypeInfo instances are singletons, but duplicates can exist |
413 uint flags() { return 0; } | 430 uint flags() { return 0; } |
414 | 431 |
415 /// Get type information on the contents of the type; null if not available | 432 /// Get type information on the contents of the type; null if not available |
416 OffsetTypeInfo[] offTi() { return null; } | 433 OffsetTypeInfo[] offTi() { return null; } |
417 } | 434 } |
435 | |
436 /+ | |
418 | 437 |
419 class TypeInfo_Typedef : TypeInfo | 438 class TypeInfo_Typedef : TypeInfo |
420 { | 439 { |
421 char[] toString() { return name; } | 440 char[] toString() { return name; } |
422 | 441 |
1019 void swap(void *p1, void *p2) | 1038 void swap(void *p1, void *p2) |
1020 { | 1039 { |
1021 assert(0); | 1040 assert(0); |
1022 } | 1041 } |
1023 } | 1042 } |
1043 | |
1044 class TypeInfo_Const : TypeInfo | |
1045 { | |
1046 char[] toString() { return "const " ~ base.toString(); } | |
1047 | |
1048 int opEquals(Object o) { return base.opEquals(o); } | |
1049 hash_t getHash(void *p) { return base.getHash(p); } | |
1050 int equals(void *p1, void *p2) { return base.equals(p1, p2); } | |
1051 int compare(void *p1, void *p2) { return base.compare(p1, p2); } | |
1052 size_t tsize() { return base.tsize(); } | |
1053 void swap(void *p1, void *p2) { return base.swap(p1, p2); } | |
1054 | |
1055 TypeInfo next() { return base.next(); } | |
1056 uint flags() { return base.flags(); } | |
1057 void[] init() { return base.init(); } | |
1058 | |
1059 TypeInfo base; | |
1060 } | |
1061 | |
1062 class TypeInfo_Invariant : TypeInfo_Const | |
1063 { | |
1064 char[] toString() { return "invariant " ~ base.toString(); } | |
1065 } | |
1066 | |
1024 +/ | 1067 +/ |
1025 | 1068 |
1026 /** | 1069 /** |
1027 * All recoverable exceptions should be derived from class Exception. | 1070 * All recoverable exceptions should be derived from class Exception. |
1028 */ | 1071 */ |
1036 this(char[] msg) | 1079 this(char[] msg) |
1037 { | 1080 { |
1038 this.msg = msg; | 1081 this.msg = msg; |
1039 } | 1082 } |
1040 | 1083 |
1041 void print() | |
1042 { | |
1043 auto str = toString(); | |
1044 printf("%.*s\n", str.length, str.ptr); | |
1045 } | |
1046 | |
1047 char[] toString() { return msg; } | 1084 char[] toString() { return msg; } |
1048 } | 1085 } |
1049 | 1086 |
1050 /** | 1087 /** |
1051 * All irrecoverable exceptions should be derived from class Error. | 1088 * All irrecoverable exceptions should be derived from class Error. |
1068 this.next = next; | 1105 this.next = next; |
1069 } | 1106 } |
1070 } | 1107 } |
1071 | 1108 |
1072 //extern (C) int nullext = 0; | 1109 //extern (C) int nullext = 0; |
1110 |