Mercurial > projects > ldc
annotate lphobos/internal/objectimpl.d @ 650:aa6a0b7968f7
Added test case for bug #100
Removed dubious check for not emitting static private global in other modules without access. This should be handled properly somewhere else, it's causing unresolved global errors for stuff that should work (in MiniD)
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Sun, 05 Oct 2008 17:28:15 +0200 |
parents | 373489eeaf90 |
children | eef8ac26c66c |
rev | line source |
---|---|
1 | 1 |
2 /** | |
3 * Part of the D programming language runtime library. | |
4 * Forms the symbols available to all D programs. Includes | |
5 * Object, which is the root of the class object hierarchy. | |
6 * | |
7 * This module is implicitly imported. | |
8 * Macros: | |
9 * WIKI = Phobos/Object | |
10 */ | |
11 | |
12 /* | |
13 * Copyright (C) 2004-2007 by Digital Mars, www.digitalmars.com | |
14 * Written by Walter Bright | |
15 * | |
16 * This software is provided 'as-is', without any express or implied | |
17 * warranty. In no event will the authors be held liable for any damages | |
18 * arising from the use of this software. | |
19 * | |
20 * Permission is granted to anyone to use this software for any purpose, | |
21 * including commercial applications, and to alter it and redistribute it | |
22 * freely, in both source and binary form, subject to the following | |
23 * restrictions: | |
24 * | |
25 * o The origin of this software must not be misrepresented; you must not | |
26 * claim that you wrote the original software. If you use this software | |
27 * in a product, an acknowledgment in the product documentation would be | |
28 * appreciated but is not required. | |
29 * o Altered source versions must be plainly marked as such, and must not | |
30 * be misrepresented as being the original software. | |
31 * o This notice may not be removed or altered from any source | |
32 * distribution. | |
33 */ | |
34 | |
89 | 35 /* |
116
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
36 * This copy is modified to work with LLVMDC |
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
37 * by Tomas Lindquist Olsen, September 2007 |
89 | 38 */ |
1 | 39 |
40 module object; | |
41 | |
89 | 42 import std.outofmemory; |
1 | 43 |
52 | 44 /** |
45 * An unsigned integral type large enough to span the memory space. Use for | |
46 * array indices and pointer offsets for maximal portability to | |
47 * architectures that have different memory address ranges. This is | |
48 * analogous to C's size_t. | |
49 */ | |
50 alias typeof(int.sizeof) size_t; | |
51 | |
52 /** | |
53 * A signed integral type large enough to span the memory space. Use for | |
54 * pointer differences and for size_t differences for maximal portability to | |
55 * architectures that have different memory address ranges. This is | |
56 * analogous to C's ptrdiff_t. | |
57 */ | |
58 alias typeof(cast(void*)0 - cast(void*)0) ptrdiff_t; | |
59 | |
60 alias size_t hash_t; | |
61 | |
1 | 62 extern (C) |
63 { /// C's printf function. | |
64 int printf(char *, ...); | |
52 | 65 void trace_term(); |
1 | 66 |
67 int memcmp(void *, void *, size_t); | |
68 void* memcpy(void *, void *, size_t); | |
69 void* calloc(size_t, size_t); | |
70 void* realloc(void*, size_t); | |
71 void free(void*); | |
72 | |
73 //Object _d_newclass(ClassInfo ci); | |
74 } | |
75 | |
76 /// Standard boolean type. | |
77 alias bool bit; | |
78 | |
52 | 79 alias char[] string; |
80 alias wchar[] wstring; | |
81 alias dchar[] dstring; | |
1 | 82 |
83 /+ | |
52 | 84 |
1 | 85 /* ************************* |
86 * Internal struct pointed to by the hidden .monitor member. | |
87 */ | |
88 struct Monitor | |
89 { | |
90 void delegate(Object)[] delegates; | |
91 | |
92 /* More stuff goes here defined by internal/monitor.c */ | |
93 } | |
52 | 94 |
1 | 95 +/ |
96 | |
97 /****************** | |
98 * All D class objects inherit from Object. | |
99 */ | |
100 class Object | |
101 { | |
102 void print() | |
103 { | |
104 char[] s = toString(); | |
105 printf("%.*s\n", s.length, s.ptr); | |
106 } | |
107 | |
108 /** | |
109 * Convert Object to a human readable string. | |
110 */ | |
111 char[] toString() | |
112 { | |
126 | 113 return this.classinfo.name; |
1 | 114 } |
115 | |
116 /** | |
117 * Compute hash function for Object. | |
118 */ | |
119 hash_t toHash() | |
120 { | |
121 // BUG: this prevents a compacting GC from working, needs to be fixed | |
52 | 122 return cast(hash_t)cast(void *)this; |
1 | 123 } |
124 | |
125 /** | |
126 * Compare with another Object obj. | |
127 * Returns: | |
128 * $(TABLE | |
129 * $(TR $(TD this < obj) $(TD < 0)) | |
130 * $(TR $(TD this == obj) $(TD 0)) | |
131 * $(TR $(TD this > obj) $(TD > 0)) | |
132 * ) | |
133 */ | |
134 int opCmp(Object o) | |
135 { | |
136 // BUG: this prevents a compacting GC from working, needs to be fixed | |
137 //return cast(int)cast(void *)this - cast(int)cast(void *)o; | |
138 | |
126 | 139 throw new Error("need opCmp for class " ~ this.classinfo.name); |
1 | 140 } |
141 | |
142 /** | |
143 * Returns !=0 if this object does have the same contents as obj. | |
144 */ | |
145 int opEquals(Object o) | |
146 { | |
147 return cast(int)(this is o); | |
148 } | |
149 | |
150 /* ** | |
151 * Call delegate dg, passing this to it, when this object gets destroyed. | |
152 * Use extreme caution, as the list of delegates is stored in a place | |
153 * not known to the gc. Thus, if any objects pointed to by one of these | |
154 * delegates gets freed by the gc, calling the delegate will cause a | |
155 * crash. | |
156 * 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. | |
158 */ | |
159 final void notifyRegister(void delegate(Object) dg) | |
160 { | |
52 | 161 /+ |
1 | 162 //printf("notifyRegister(dg = %llx, o = %p)\n", dg, this); |
52 | 163 synchronized (this) |
1 | 164 { |
165 Monitor* m = cast(Monitor*)(cast(void**)this)[1]; | |
166 foreach (inout x; m.delegates) | |
167 { | |
168 if (!x || x == dg) | |
169 { x = dg; | |
170 return; | |
171 } | |
172 } | |
173 | |
174 // Increase size of delegates[] | |
175 auto len = m.delegates.length; | |
176 auto startlen = len; | |
177 if (len == 0) | |
178 { | |
179 len = 4; | |
180 auto p = calloc((void delegate(Object)).sizeof, len); | |
181 if (!p) | |
182 _d_OutOfMemory(); | |
183 m.delegates = (cast(void delegate(Object)*)p)[0 .. len]; | |
184 } | |
185 else | |
186 { | |
187 len += len + 4; | |
188 auto p = realloc(m.delegates.ptr, (void delegate(Object)).sizeof * len); | |
189 if (!p) | |
190 _d_OutOfMemory(); | |
191 m.delegates = (cast(void delegate(Object)*)p)[0 .. len]; | |
192 m.delegates[startlen .. len] = null; | |
193 } | |
194 m.delegates[startlen] = dg; | |
52 | 195 } |
196 +/ | |
1 | 197 } |
198 | |
199 /* ** | |
200 * Remove delegate dg from the notify list. | |
201 * This is only for use by library developers, as it will need to be | |
202 * redone if weak pointers are added or a moving gc is developed. | |
203 */ | |
204 final void notifyUnRegister(void delegate(Object) dg) | |
205 { | |
52 | 206 /+ |
207 synchronized (this) | |
1 | 208 { |
209 Monitor* m = cast(Monitor*)(cast(void**)this)[1]; | |
210 foreach (inout x; m.delegates) | |
211 { | |
212 if (x == dg) | |
213 x = null; | |
214 } | |
52 | 215 } |
216 +/ | |
1 | 217 } |
218 | |
219 /****** | |
220 * Create instance of class specified by classname. | |
221 * The class must either have no constructors or have | |
222 * a default constructor. | |
223 * Returns: | |
224 * null if failed | |
225 */ | |
52 | 226 static Object factory(char[] classname) |
1 | 227 { |
52 | 228 /+ |
42 | 229 auto ci = ClassInfo.find(classname); |
1 | 230 if (ci) |
231 { | |
232 return ci.create(); | |
42 | 233 } |
52 | 234 +/ |
1 | 235 return null; |
52 | 236 } |
1 | 237 } |
238 | |
239 /+ | |
240 extern (C) void _d_notify_release(Object o) | |
241 { | |
242 //printf("_d_notify_release(o = %p)\n", o); | |
243 Monitor* m = cast(Monitor*)(cast(void**)o)[1]; | |
244 if (m.delegates.length) | |
245 { | |
246 auto dgs = m.delegates; | |
247 synchronized (o) | |
248 { | |
249 dgs = m.delegates; | |
250 m.delegates = null; | |
251 } | |
252 | |
253 foreach (dg; dgs) | |
254 { | |
255 if (dg) | |
256 { //printf("calling dg = %llx (%p)\n", dg, o); | |
257 dg(o); | |
258 } | |
259 } | |
260 | |
261 free(dgs.ptr); | |
262 } | |
263 } | |
264 | |
89 | 265 +/ |
266 | |
1 | 267 /** |
268 * Information about an interface. | |
269 * A pointer to this appears as the first entry in the interface's vtbl[]. | |
270 */ | |
271 struct Interface | |
272 { | |
273 ClassInfo classinfo; /// .classinfo for this interface (not for containing class) | |
274 void *[] vtbl; | |
275 int offset; /// offset to Interface 'this' from Object 'this' | |
276 } | |
277 | |
278 import std.moduleinit; | |
89 | 279 |
1 | 280 /** |
281 * Runtime type information about a class. Can be retrieved for any class type | |
282 * or instance by using the .classinfo property. | |
283 * A pointer to this appears as the first entry in the class's vtbl[]. | |
284 */ | |
285 class ClassInfo : Object | |
286 { | |
287 byte[] init; /** class static initializer | |
288 * (init.length gives size in bytes of class) | |
289 */ | |
290 char[] name; /// class name | |
291 void *[] vtbl; /// virtual function pointer table | |
292 Interface[] interfaces; /// interfaces this class implements | |
293 ClassInfo base; /// base class | |
294 void *destructor; | |
89 | 295 void function(Object) classInvariant; |
1 | 296 uint flags; |
297 // 1: // IUnknown | |
298 // 2: // has no possible pointers into GC memory | |
299 // 4: // has offTi[] member | |
300 // 8: // has constructors | |
301 void *deallocator; | |
302 OffsetTypeInfo[] offTi; | |
303 void function(Object) defaultConstructor; // default Constructor | |
304 | |
305 /************* | |
306 * Search all modules for ClassInfo corresponding to classname. | |
307 * Returns: null if not found | |
308 */ | |
309 static ClassInfo find(char[] classname) | |
310 { | |
89 | 311 /+foreach (m; ModuleInfo.modules()) |
1 | 312 { |
313 //writefln("module %s, %d", m.name, m.localClasses.length); | |
314 foreach (c; m.localClasses) | |
315 { | |
316 //writefln("\tclass %s", c.name); | |
317 if (c.name == classname) | |
318 return c; | |
319 } | |
89 | 320 }+/ |
1 | 321 return null; |
322 } | |
323 | |
324 /******************** | |
325 * Create instance of Object represented by 'this'. | |
326 */ | |
327 Object create() | |
328 { | |
89 | 329 /+if (flags & 8 && !defaultConstructor) |
1 | 330 return null; |
331 Object o = _d_newclass(this); | |
332 if (flags & 8 && defaultConstructor) | |
333 { | |
334 defaultConstructor(o); | |
335 } | |
336 return o; | |
89 | 337 +/ |
338 return null; | |
1 | 339 } |
340 } | |
341 | |
89 | 342 //private import std.string; |
1 | 343 |
52 | 344 |
1 | 345 /** |
346 * Array of pairs giving the offset and type information for each | |
347 * member in an aggregate. | |
348 */ | |
349 struct OffsetTypeInfo | |
350 { | |
351 size_t offset; /// Offset of member from start of object | |
352 TypeInfo ti; /// TypeInfo for this member | |
353 } | |
354 | |
52 | 355 private int string_cmp(char[] s1, char[] s2) |
356 { | |
357 auto len = s1.length; | |
358 if (s2.length < len) | |
359 len = s2.length; | |
360 int result = memcmp(s1.ptr, s2.ptr, len); | |
361 if (result == 0) | |
362 result = cast(int)(cast(ptrdiff_t)s1.length - cast(ptrdiff_t)s2.length); | |
363 return result; | |
364 } | |
365 | |
1 | 366 /** |
367 * Runtime type information about a type. | |
368 * Can be retrieved for any type using a | |
369 * <a href="../expression.html#typeidexpression">TypeidExpression</a>. | |
370 */ | |
371 class TypeInfo | |
372 { | |
373 hash_t toHash() | |
374 { hash_t hash; | |
375 | |
376 foreach (char c; this.toString()) | |
377 hash = hash * 9 + c; | |
378 return hash; | |
379 } | |
380 | |
381 int opCmp(Object o) | |
382 { | |
383 if (this is o) | |
384 return 0; | |
385 TypeInfo ti = cast(TypeInfo)o; | |
386 if (ti is null) | |
387 return 1; | |
52 | 388 return string_cmp(this.toString(), ti.toString()); |
1 | 389 } |
390 | |
391 int opEquals(Object o) | |
392 { | |
393 /* TypeInfo instances are singletons, but duplicates can exist | |
394 * across DLL's. Therefore, comparing for a name match is | |
395 * sufficient. | |
396 */ | |
397 if (this is o) | |
398 return 1; | |
399 TypeInfo ti = cast(TypeInfo)o; | |
400 return cast(int)(ti && this.toString() == ti.toString()); | |
401 } | |
402 | |
403 /// Returns a hash of the instance of a type. | |
404 hash_t getHash(void *p) { return cast(uint)p; } | |
405 | |
406 /// Compares two instances for equality. | |
407 int equals(void *p1, void *p2) { return cast(int)(p1 == p2); } | |
408 | |
409 /// Compares two instances for <, ==, or >. | |
410 int compare(void *p1, void *p2) { return 0; } | |
411 | |
412 /// Returns size of the type. | |
413 size_t tsize() { return 0; } | |
414 | |
415 /// Swaps two instances of the type. | |
416 void swap(void *p1, void *p2) | |
417 { | |
418 size_t n = tsize(); | |
419 for (size_t i = 0; i < n; i++) | |
420 { byte t; | |
421 | |
422 t = (cast(byte *)p1)[i]; | |
423 (cast(byte *)p1)[i] = (cast(byte *)p2)[i]; | |
424 (cast(byte *)p2)[i] = t; | |
425 } | |
426 } | |
427 | |
428 /// Get TypeInfo for 'next' type, as defined by what kind of type this is, | |
429 /// null if none. | |
430 TypeInfo next() { return null; } | |
431 | |
432 /// Return default initializer, null if default initialize to 0 | |
433 void[] init() { return null; } | |
434 | |
435 /// Get flags for type: 1 means GC should scan for pointers | |
436 uint flags() { return 0; } | |
437 | |
438 /// Get type information on the contents of the type; null if not available | |
439 OffsetTypeInfo[] offTi() { return null; } | |
440 } | |
441 | |
442 class TypeInfo_Typedef : TypeInfo | |
443 { | |
444 char[] toString() { return name; } | |
445 | |
446 int opEquals(Object o) | |
447 { TypeInfo_Typedef c; | |
448 | |
449 return cast(int) | |
450 (this is o || | |
451 ((c = cast(TypeInfo_Typedef)o) !is null && | |
452 this.name == c.name && | |
453 this.base == c.base)); | |
454 } | |
455 | |
456 hash_t getHash(void *p) { return base.getHash(p); } | |
457 int equals(void *p1, void *p2) { return base.equals(p1, p2); } | |
458 int compare(void *p1, void *p2) { return base.compare(p1, p2); } | |
459 size_t tsize() { return base.tsize(); } | |
460 void swap(void *p1, void *p2) { return base.swap(p1, p2); } | |
461 | |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
462 TypeInfo next() { return base; } |
1 | 463 uint flags() { return base.flags(); } |
464 void[] init() { return m_init.length ? m_init : base.init(); } | |
465 | |
466 TypeInfo base; | |
467 char[] name; | |
468 void[] m_init; | |
469 } | |
470 | |
471 class TypeInfo_Enum : TypeInfo_Typedef | |
472 { | |
473 } | |
474 | |
475 class TypeInfo_Pointer : TypeInfo | |
476 { | |
477 char[] toString() { return m_next.toString() ~ "*"; } | |
478 | |
479 int opEquals(Object o) | |
480 { TypeInfo_Pointer c; | |
481 | |
482 return this is o || | |
483 ((c = cast(TypeInfo_Pointer)o) !is null && | |
484 this.m_next == c.m_next); | |
485 } | |
486 | |
487 hash_t getHash(void *p) | |
488 { | |
489 return cast(uint)*cast(void* *)p; | |
490 } | |
491 | |
492 int equals(void *p1, void *p2) | |
493 { | |
494 return cast(int)(*cast(void* *)p1 == *cast(void* *)p2); | |
495 } | |
496 | |
497 int compare(void *p1, void *p2) | |
498 { | |
499 if (*cast(void* *)p1 < *cast(void* *)p2) | |
500 return -1; | |
501 else if (*cast(void* *)p1 > *cast(void* *)p2) | |
502 return 1; | |
503 else | |
504 return 0; | |
505 } | |
506 | |
507 size_t tsize() | |
508 { | |
509 return (void*).sizeof; | |
510 } | |
511 | |
512 void swap(void *p1, void *p2) | |
513 { void* tmp; | |
514 tmp = *cast(void**)p1; | |
515 *cast(void**)p1 = *cast(void**)p2; | |
516 *cast(void**)p2 = tmp; | |
517 } | |
518 | |
519 TypeInfo next() { return m_next; } | |
520 uint flags() { return 1; } | |
521 | |
522 TypeInfo m_next; | |
523 } | |
524 | |
525 class TypeInfo_Array : TypeInfo | |
526 { | |
527 char[] toString() { return value.toString() ~ "[]"; } | |
528 | |
529 int opEquals(Object o) | |
530 { TypeInfo_Array c; | |
531 | |
532 return cast(int) | |
533 (this is o || | |
534 ((c = cast(TypeInfo_Array)o) !is null && | |
535 this.value == c.value)); | |
536 } | |
537 | |
538 hash_t getHash(void *p) | |
539 { size_t sz = value.tsize(); | |
540 hash_t hash = 0; | |
541 void[] a = *cast(void[]*)p; | |
542 for (size_t i = 0; i < a.length; i++) | |
543 hash += value.getHash(a.ptr + i * sz); | |
544 return hash; | |
545 } | |
546 | |
547 int equals(void *p1, void *p2) | |
548 { | |
549 void[] a1 = *cast(void[]*)p1; | |
550 void[] a2 = *cast(void[]*)p2; | |
551 if (a1.length != a2.length) | |
552 return 0; | |
553 size_t sz = value.tsize(); | |
554 for (size_t i = 0; i < a1.length; i++) | |
555 { | |
556 if (!value.equals(a1.ptr + i * sz, a2.ptr + i * sz)) | |
557 return 0; | |
558 } | |
559 return 1; | |
560 } | |
561 | |
562 int compare(void *p1, void *p2) | |
563 { | |
564 void[] a1 = *cast(void[]*)p1; | |
565 void[] a2 = *cast(void[]*)p2; | |
566 size_t sz = value.tsize(); | |
567 size_t len = a1.length; | |
568 | |
569 if (a2.length < len) | |
570 len = a2.length; | |
571 for (size_t u = 0; u < len; u++) | |
572 { | |
573 int result = value.compare(a1.ptr + u * sz, a2.ptr + u * sz); | |
574 if (result) | |
575 return result; | |
576 } | |
577 return cast(int)a1.length - cast(int)a2.length; | |
578 } | |
579 | |
580 size_t tsize() | |
581 { | |
582 return (void[]).sizeof; | |
583 } | |
584 | |
585 void swap(void *p1, void *p2) | |
586 { void[] tmp; | |
587 tmp = *cast(void[]*)p1; | |
588 *cast(void[]*)p1 = *cast(void[]*)p2; | |
589 *cast(void[]*)p2 = tmp; | |
590 } | |
591 | |
592 TypeInfo value; | |
593 | |
594 TypeInfo next() | |
595 { | |
596 return value; | |
597 } | |
598 | |
599 uint flags() { return 1; } | |
600 } | |
601 | |
58
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
602 private const char[10] digits = "0123456789"; /// 0..9 |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
603 |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
604 private char[] lengthToString(uint u) |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
605 { char[uint.sizeof * 3] buffer = void; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
606 int ndigits; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
607 char[] result; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
608 |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
609 ndigits = 0; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
610 if (u < 10) |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
611 // Avoid storage allocation for simple stuff |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
612 result = digits[u .. u + 1]; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
613 else |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
614 { |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
615 while (u) |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
616 { |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
617 uint c = (u % 10) + '0'; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
618 u /= 10; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
619 ndigits++; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
620 buffer[buffer.length - ndigits] = cast(char)c; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
621 } |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
622 result = new char[ndigits]; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
623 result[] = buffer[buffer.length - ndigits .. buffer.length]; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
624 } |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
625 return result; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
626 } |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
627 |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
628 private char[] lengthToString(ulong u) |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
629 { char[ulong.sizeof * 3] buffer; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
630 int ndigits; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
631 char[] result; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
632 |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
633 if (u < 0x1_0000_0000) |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
634 return lengthToString(cast(uint)u); |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
635 ndigits = 0; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
636 while (u) |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
637 { |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
638 char c = cast(char)((u % 10) + '0'); |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
639 u /= 10; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
640 ndigits++; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
641 buffer[buffer.length - ndigits] = c; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
642 } |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
643 result = new char[ndigits]; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
644 result[] = buffer[buffer.length - ndigits .. buffer.length]; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
645 return result; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
646 } |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
647 |
1 | 648 class TypeInfo_StaticArray : TypeInfo |
649 { | |
650 char[] toString() | |
651 { | |
58
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
652 return value.toString() ~ "[" ~ lengthToString(len) ~ "]"; |
1 | 653 } |
654 | |
655 int opEquals(Object o) | |
656 { TypeInfo_StaticArray c; | |
657 | |
658 return cast(int) | |
659 (this is o || | |
660 ((c = cast(TypeInfo_StaticArray)o) !is null && | |
661 this.len == c.len && | |
662 this.value == c.value)); | |
663 } | |
664 | |
665 hash_t getHash(void *p) | |
666 { size_t sz = value.tsize(); | |
667 hash_t hash = 0; | |
668 for (size_t i = 0; i < len; i++) | |
669 hash += value.getHash(p + i * sz); | |
670 return hash; | |
671 } | |
672 | |
673 int equals(void *p1, void *p2) | |
674 { | |
675 size_t sz = value.tsize(); | |
676 | |
677 for (size_t u = 0; u < len; u++) | |
678 { | |
679 if (!value.equals(p1 + u * sz, p2 + u * sz)) | |
680 return 0; | |
681 } | |
682 return 1; | |
683 } | |
684 | |
685 int compare(void *p1, void *p2) | |
686 { | |
687 size_t sz = value.tsize(); | |
688 | |
689 for (size_t u = 0; u < len; u++) | |
690 { | |
691 int result = value.compare(p1 + u * sz, p2 + u * sz); | |
692 if (result) | |
693 return result; | |
694 } | |
695 return 0; | |
696 } | |
697 | |
698 size_t tsize() | |
699 { | |
700 return len * value.tsize(); | |
701 } | |
702 | |
703 void swap(void *p1, void *p2) | |
704 { void* tmp; | |
705 size_t sz = value.tsize(); | |
706 ubyte[16] buffer; | |
707 void* pbuffer; | |
708 | |
709 if (sz < buffer.sizeof) | |
710 tmp = buffer.ptr; | |
58
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
711 else { |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
712 if (value.flags() & 1) |
1 | 713 tmp = pbuffer = (new void[sz]).ptr; |
58
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
714 else |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
715 tmp = pbuffer = (new byte[sz]).ptr; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
54
diff
changeset
|
716 } |
1 | 717 |
718 for (size_t u = 0; u < len; u += sz) | |
719 { size_t o = u * sz; | |
720 memcpy(tmp, p1 + o, sz); | |
721 memcpy(p1 + o, p2 + o, sz); | |
722 memcpy(p2 + o, tmp, sz); | |
723 } | |
724 if (pbuffer) | |
725 delete pbuffer; | |
726 } | |
727 | |
728 void[] init() { return value.init(); } | |
729 TypeInfo next() { return value; } | |
730 uint flags() { return value.flags(); } | |
731 | |
732 TypeInfo value; | |
733 size_t len; | |
734 } | |
735 | |
736 class TypeInfo_AssociativeArray : TypeInfo | |
737 { | |
738 char[] toString() | |
739 { | |
740 return value.toString() ~ "[" ~ key.toString() ~ "]"; | |
741 } | |
742 | |
743 int opEquals(Object o) | |
744 { TypeInfo_AssociativeArray c; | |
745 | |
746 return this is o || | |
747 ((c = cast(TypeInfo_AssociativeArray)o) !is null && | |
748 this.key == c.key && | |
749 this.value == c.value); | |
750 } | |
751 | |
752 // BUG: need to add the rest of the functions | |
753 | |
754 size_t tsize() | |
755 { | |
756 return (char[int]).sizeof; | |
757 } | |
758 | |
759 TypeInfo next() { return value; } | |
760 uint flags() { return 1; } | |
761 | |
762 TypeInfo value; | |
763 TypeInfo key; | |
764 } | |
765 | |
766 class TypeInfo_Function : TypeInfo | |
767 { | |
768 char[] toString() | |
769 { | |
770 return next.toString() ~ "()"; | |
771 } | |
772 | |
773 int opEquals(Object o) | |
774 { TypeInfo_Function c; | |
775 | |
776 return this is o || | |
777 ((c = cast(TypeInfo_Function)o) !is null && | |
778 this.next == c.next); | |
779 } | |
780 | |
781 // BUG: need to add the rest of the functions | |
782 | |
783 size_t tsize() | |
784 { | |
785 return 0; // no size for functions | |
786 } | |
787 | |
788 TypeInfo next; | |
789 } | |
790 | |
791 class TypeInfo_Delegate : TypeInfo | |
792 { | |
793 char[] toString() | |
794 { | |
795 return next.toString() ~ " delegate()"; | |
796 } | |
797 | |
798 int opEquals(Object o) | |
799 { TypeInfo_Delegate c; | |
800 | |
801 return this is o || | |
802 ((c = cast(TypeInfo_Delegate)o) !is null && | |
803 this.next == c.next); | |
804 } | |
805 | |
806 // BUG: need to add the rest of the functions | |
807 | |
808 size_t tsize() | |
809 { alias int delegate() dg; | |
810 return dg.sizeof; | |
811 } | |
812 | |
813 uint flags() { return 1; } | |
814 | |
815 TypeInfo next; | |
816 } | |
817 | |
818 class TypeInfo_Class : TypeInfo | |
819 { | |
820 char[] toString() { return info.name; } | |
821 | |
822 int opEquals(Object o) | |
823 { TypeInfo_Class c; | |
824 | |
825 return this is o || | |
826 ((c = cast(TypeInfo_Class)o) !is null && | |
827 this.info.name == c.classinfo.name); | |
828 } | |
829 | |
830 hash_t getHash(void *p) | |
831 { | |
832 Object o = *cast(Object*)p; | |
833 assert(o); | |
834 return o.toHash(); | |
835 } | |
836 | |
837 int equals(void *p1, void *p2) | |
838 { | |
839 Object o1 = *cast(Object*)p1; | |
840 Object o2 = *cast(Object*)p2; | |
841 | |
842 return (o1 is o2) || (o1 && o1.opEquals(o2)); | |
843 } | |
844 | |
845 int compare(void *p1, void *p2) | |
846 { | |
847 Object o1 = *cast(Object*)p1; | |
848 Object o2 = *cast(Object*)p2; | |
849 int c = 0; | |
850 | |
851 // Regard null references as always being "less than" | |
852 if (o1 !is o2) | |
853 { | |
854 if (o1) | |
855 { if (!o2) | |
856 c = 1; | |
857 else | |
858 c = o1.opCmp(o2); | |
859 } | |
860 else | |
861 c = -1; | |
862 } | |
863 return c; | |
864 } | |
865 | |
866 size_t tsize() | |
867 { | |
868 return Object.sizeof; | |
869 } | |
870 | |
871 uint flags() { return 1; } | |
872 | |
873 OffsetTypeInfo[] offTi() | |
874 { | |
875 return (info.flags & 4) ? info.offTi : null; | |
876 } | |
877 | |
878 ClassInfo info; | |
879 } | |
880 | |
881 class TypeInfo_Interface : TypeInfo | |
882 { | |
883 char[] toString() { return info.name; } | |
884 | |
885 int opEquals(Object o) | |
886 { TypeInfo_Interface c; | |
887 | |
888 return this is o || | |
889 ((c = cast(TypeInfo_Interface)o) !is null && | |
890 this.info.name == c.classinfo.name); | |
891 } | |
892 | |
893 hash_t getHash(void *p) | |
894 { | |
895 Interface* pi = **cast(Interface ***)*cast(void**)p; | |
896 Object o = cast(Object)(*cast(void**)p - pi.offset); | |
897 assert(o); | |
898 return o.toHash(); | |
899 } | |
900 | |
901 int equals(void *p1, void *p2) | |
902 { | |
903 Interface* pi = **cast(Interface ***)*cast(void**)p1; | |
904 Object o1 = cast(Object)(*cast(void**)p1 - pi.offset); | |
905 pi = **cast(Interface ***)*cast(void**)p2; | |
906 Object o2 = cast(Object)(*cast(void**)p2 - pi.offset); | |
907 | |
908 return o1 == o2 || (o1 && o1.opCmp(o2) == 0); | |
909 } | |
910 | |
911 int compare(void *p1, void *p2) | |
912 { | |
913 Interface* pi = **cast(Interface ***)*cast(void**)p1; | |
914 Object o1 = cast(Object)(*cast(void**)p1 - pi.offset); | |
915 pi = **cast(Interface ***)*cast(void**)p2; | |
916 Object o2 = cast(Object)(*cast(void**)p2 - pi.offset); | |
917 int c = 0; | |
918 | |
919 // Regard null references as always being "less than" | |
920 if (o1 != o2) | |
921 { | |
922 if (o1) | |
923 { if (!o2) | |
924 c = 1; | |
925 else | |
926 c = o1.opCmp(o2); | |
927 } | |
928 else | |
929 c = -1; | |
930 } | |
931 return c; | |
932 } | |
933 | |
934 size_t tsize() | |
935 { | |
936 return Object.sizeof; | |
937 } | |
938 | |
939 uint flags() { return 1; } | |
940 | |
941 ClassInfo info; | |
942 } | |
943 | |
944 class TypeInfo_Struct : TypeInfo | |
945 { | |
946 char[] toString() { return name; } | |
947 | |
948 int opEquals(Object o) | |
949 { TypeInfo_Struct s; | |
950 | |
951 return this is o || | |
952 ((s = cast(TypeInfo_Struct)o) !is null && | |
953 this.name == s.name && | |
954 this.init.length == s.init.length); | |
955 } | |
956 | |
957 hash_t getHash(void *p) | |
958 { hash_t h; | |
959 | |
960 assert(p); | |
961 if (xtoHash) | |
962 { //printf("getHash() using xtoHash\n"); | |
963 h = (*xtoHash)(p); | |
964 } | |
965 else | |
966 { | |
967 //printf("getHash() using default hash\n"); | |
968 // A sorry hash algorithm. | |
969 // Should use the one for strings. | |
970 // BUG: relies on the GC not moving objects | |
971 for (size_t i = 0; i < init.length; i++) | |
972 { h = h * 9 + *cast(ubyte*)p; | |
973 p++; | |
974 } | |
975 } | |
976 return h; | |
977 } | |
978 | |
73 | 979 int equals(void *p1, void *p2) |
1 | 980 { int c; |
981 | |
982 if (p1 == p2) | |
983 c = 1; | |
984 else if (!p1 || !p2) | |
985 c = 0; | |
986 else if (xopEquals) | |
987 c = (*xopEquals)(p1, p2); | |
988 else | |
989 // BUG: relies on the GC not moving objects | |
990 c = (memcmp(p1, p2, init.length) == 0); | |
991 return c; | |
992 } | |
993 | |
72 | 994 int compare(void *p1, void *p2) |
1 | 995 { |
996 int c = 0; | |
997 | |
998 // Regard null references as always being "less than" | |
999 if (p1 != p2) | |
1000 { | |
1001 if (p1) | |
1002 { if (!p2) | |
1003 c = 1; | |
1004 else if (xopCmp) | |
1005 c = (*xopCmp)(p1, p2); | |
1006 else | |
1007 // BUG: relies on the GC not moving objects | |
1008 c = memcmp(p1, p2, init.length); | |
1009 } | |
1010 else | |
1011 c = -1; | |
1012 } | |
1013 return c; | |
1014 } | |
1015 | |
1016 size_t tsize() | |
1017 { | |
1018 return init.length; | |
1019 } | |
1020 | |
1021 void[] init() { return m_init; } | |
1022 | |
1023 uint flags() { return m_flags; } | |
1024 | |
1025 char[] name; | |
1026 void[] m_init; // initializer; init.ptr == null if 0 initialize | |
1027 | |
1028 hash_t function(void*) xtoHash; | |
1029 int function(void*,void*) xopEquals; | |
1030 int function(void*,void*) xopCmp; | |
1031 char[] function(void*) xtoString; | |
1032 | |
1033 uint m_flags; | |
1034 } | |
1035 | |
1036 class TypeInfo_Tuple : TypeInfo | |
1037 { | |
1038 TypeInfo[] elements; | |
1039 | |
1040 char[] toString() | |
1041 { | |
1042 char[] s; | |
1043 s = "("; | |
1044 foreach (i, element; elements) | |
1045 { | |
1046 if (i) | |
1047 s ~= ','; | |
1048 s ~= element.toString(); | |
1049 } | |
1050 s ~= ")"; | |
1051 return s; | |
1052 } | |
1053 | |
1054 int opEquals(Object o) | |
1055 { | |
1056 if (this is o) | |
1057 return 1; | |
1058 | |
1059 auto t = cast(TypeInfo_Tuple)o; | |
1060 if (t && elements.length == t.elements.length) | |
1061 { | |
1062 for (size_t i = 0; i < elements.length; i++) | |
1063 { | |
1064 if (elements[i] != t.elements[i]) | |
1065 return 0; | |
1066 } | |
1067 return 1; | |
1068 } | |
1069 return 0; | |
1070 } | |
1071 | |
1072 hash_t getHash(void *p) | |
1073 { | |
1074 assert(0); | |
1075 } | |
1076 | |
1077 int equals(void *p1, void *p2) | |
1078 { | |
1079 assert(0); | |
1080 } | |
1081 | |
1082 int compare(void *p1, void *p2) | |
1083 { | |
1084 assert(0); | |
1085 } | |
1086 | |
1087 size_t tsize() | |
1088 { | |
1089 assert(0); | |
1090 } | |
1091 | |
1092 void swap(void *p1, void *p2) | |
1093 { | |
1094 assert(0); | |
1095 } | |
1096 } | |
52 | 1097 |
1098 class TypeInfo_Const : TypeInfo | |
1099 { | |
1100 char[] toString() { return "const " ~ base.toString(); } | |
1101 | |
1102 int opEquals(Object o) { return base.opEquals(o); } | |
1103 hash_t getHash(void *p) { return base.getHash(p); } | |
1104 int equals(void *p1, void *p2) { return base.equals(p1, p2); } | |
1105 int compare(void *p1, void *p2) { return base.compare(p1, p2); } | |
1106 size_t tsize() { return base.tsize(); } | |
1107 void swap(void *p1, void *p2) { return base.swap(p1, p2); } | |
1108 | |
1109 TypeInfo next() { return base.next(); } | |
1110 uint flags() { return base.flags(); } | |
1111 void[] init() { return base.init(); } | |
1112 | |
1113 TypeInfo base; | |
1114 } | |
1115 | |
1116 class TypeInfo_Invariant : TypeInfo_Const | |
1117 { | |
1118 char[] toString() { return "invariant " ~ base.toString(); } | |
1119 } | |
1120 | |
1 | 1121 /** |
116
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
1122 * Information about each module. |
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
1123 */ |
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
1124 class ModuleInfo |
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
1125 { |
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
1126 char[] name; |
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
1127 ModuleInfo[] importedModules; |
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
1128 ClassInfo[] localClasses; |
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
1129 |
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
1130 uint flags; // initialization state |
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
1131 |
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
1132 void function() ctor; |
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
1133 void function() dtor; |
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
1134 void function() unitTest; |
473
373489eeaf90
Applied downs' lphobos update
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
126
diff
changeset
|
1135 |
373489eeaf90
Applied downs' lphobos update
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
126
diff
changeset
|
1136 void* xgetMembers; |
373489eeaf90
Applied downs' lphobos update
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
126
diff
changeset
|
1137 void function() ictor; |
116
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
1138 |
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
1139 /****************** |
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
1140 * Return collection of all modules in the program. |
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
1141 */ |
473
373489eeaf90
Applied downs' lphobos update
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
126
diff
changeset
|
1142 static int opApply(int delegate(ref ModuleInfo) dg) { |
373489eeaf90
Applied downs' lphobos update
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
126
diff
changeset
|
1143 foreach (ref mod; std.moduleinit._moduleinfo_array) |
373489eeaf90
Applied downs' lphobos update
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
126
diff
changeset
|
1144 if (auto i = dg(mod)) return i; |
373489eeaf90
Applied downs' lphobos update
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
126
diff
changeset
|
1145 return 0; |
116
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
1146 } |
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
1147 } |
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
1148 |
473
373489eeaf90
Applied downs' lphobos update
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
126
diff
changeset
|
1149 struct ModuleReference |
373489eeaf90
Applied downs' lphobos update
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
126
diff
changeset
|
1150 { |
373489eeaf90
Applied downs' lphobos update
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
126
diff
changeset
|
1151 ModuleReference* next; |
373489eeaf90
Applied downs' lphobos update
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
126
diff
changeset
|
1152 ModuleInfo mod; |
373489eeaf90
Applied downs' lphobos update
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
126
diff
changeset
|
1153 } |
373489eeaf90
Applied downs' lphobos update
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
126
diff
changeset
|
1154 extern(C) ModuleReference* _Dmodule_ref; |
373489eeaf90
Applied downs' lphobos update
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
126
diff
changeset
|
1155 |
116
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
1156 /** |
1 | 1157 * All recoverable exceptions should be derived from class Exception. |
1158 */ | |
1159 class Exception : Object | |
1160 { | |
1161 char[] msg; | |
1162 | |
1163 /** | |
1164 * Constructor; msg is a descriptive message for the exception. | |
1165 */ | |
1166 this(char[] msg) | |
1167 { | |
1168 this.msg = msg; | |
1169 } | |
1170 | |
86
fd32135dca3e
[svn r90] Major updates to the gen directory. Redesigned the 'elem' struct. Much more... !!!
lindquist
parents:
73
diff
changeset
|
1171 void print() |
fd32135dca3e
[svn r90] Major updates to the gen directory. Redesigned the 'elem' struct. Much more... !!!
lindquist
parents:
73
diff
changeset
|
1172 { |
fd32135dca3e
[svn r90] Major updates to the gen directory. Redesigned the 'elem' struct. Much more... !!!
lindquist
parents:
73
diff
changeset
|
1173 char[] s = toString(); |
fd32135dca3e
[svn r90] Major updates to the gen directory. Redesigned the 'elem' struct. Much more... !!!
lindquist
parents:
73
diff
changeset
|
1174 printf("%.*s\n", s.length, s.ptr); |
fd32135dca3e
[svn r90] Major updates to the gen directory. Redesigned the 'elem' struct. Much more... !!!
lindquist
parents:
73
diff
changeset
|
1175 } |
fd32135dca3e
[svn r90] Major updates to the gen directory. Redesigned the 'elem' struct. Much more... !!!
lindquist
parents:
73
diff
changeset
|
1176 |
1 | 1177 char[] toString() { return msg; } |
1178 } | |
1179 | |
1180 /** | |
1181 * All irrecoverable exceptions should be derived from class Error. | |
1182 */ | |
1183 class Error : Exception | |
1184 { | |
1185 Error next; | |
1186 | |
1187 /** | |
1188 * Constructor; msg is a descriptive message for the exception. | |
1189 */ | |
1190 this(char[] msg) | |
1191 { | |
1192 super(msg); | |
1193 } | |
1194 | |
1195 this(char[] msg, Error next) | |
1196 { | |
1197 super(msg); | |
1198 this.next = next; | |
1199 } | |
1200 } | |
1201 | |
1202 //extern (C) int nullext = 0; |