root/trunk/import/object.di

Revision 519, 11.4 kB (checked in by jmdavis, 1 year ago)

Added Throwable and default arguments to most Exception and Error constructors.

For whatever reason, a number of Exception and Error types didn't take a
Throwable for chaining exceptions, and most of them didn't have default
arguments for file and line number (some didn't even take file and line
number in the first place). So, most of the Exception and Error types in
core.exception and object_.d/object.di now have take an optional
Throwable argument and optional file and line number arguments which
default to FILE and LINE. In at least one case (AssertError?), I
couldn't make it take default arguments for file and line number without
breaking code, so it doesn't. But if I could do it and maintain
backwards comptability, I did. I also added unit tests to verify that
the various constructors work properly.

  • Property svn:eol-style set to native
Line 
1 /**
2  * Contains all implicitly declared types and variables.
3  *
4  * Copyright: Copyright Digital Mars 2000 - 2011.
5  * License:   <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
6  * Authors:   Walter Bright, Sean Kelly
7  *
8  *          Copyright Digital Mars 2000 - 2011.
9  * Distributed under the Boost Software License, Version 1.0.
10  *    (See accompanying file LICENSE_1_0.txt or copy at
11  *          http://www.boost.org/LICENSE_1_0.txt)
12  */
13 module object;
14
15 alias typeof(int.sizeof)                    size_t;
16 alias typeof(cast(void*)0 - cast(void*)0)   ptrdiff_t;
17 alias ptrdiff_t                             sizediff_t;
18
19 alias size_t hash_t;
20 alias bool equals_t;
21
22 alias immutable(char)[]  string;
23 alias immutable(wchar)[] wstring;
24 alias immutable(dchar)[] dstring;
25
26 class Object
27 {
28     string   toString();
29     hash_t   toHash();
30     int      opCmp(Object o);
31     equals_t opEquals(Object o);
32     equals_t opEquals(Object lhs, Object rhs);
33
34     interface Monitor
35     {
36         void lock();
37         void unlock();
38     }
39
40     static Object factory(string classname);
41 }
42
43 bool opEquals(Object lhs, Object rhs);
44 //bool opEquals(TypeInfo lhs, TypeInfo rhs);
45
46 void setSameMutex(shared Object ownee, shared Object owner);
47
48 struct Interface
49 {
50     TypeInfo_Class   classinfo;
51     void*[]     vtbl;
52     ptrdiff_t   offset;   // offset to Interface 'this' from Object 'this'
53 }
54
55 struct OffsetTypeInfo
56 {
57     size_t   offset;
58     TypeInfo ti;
59 }
60
61 class TypeInfo
62 {
63     hash_t   getHash(in void* p);
64     equals_t equals(in void* p1, in void* p2);
65     int      compare(in void* p1, in void* p2);
66     size_t   tsize();
67     void     swap(void* p1, void* p2);
68     TypeInfo next();
69     void[]   init();
70     uint     flags();
71     // 1:    // has possible pointers into GC memory
72     OffsetTypeInfo[] offTi();
73     void destroy(void* p);
74     void postblit(void* p);
75     size_t talign();
76     version (X86_64) int argTypes(out TypeInfo arg1, out TypeInfo arg2);
77 }
78
79 class TypeInfo_Typedef : TypeInfo
80 {
81     TypeInfo base;
82     string   name;
83     void[]   m_init;
84 }
85
86 class TypeInfo_Enum : TypeInfo_Typedef
87 {
88
89 }
90
91 class TypeInfo_Pointer : TypeInfo
92 {
93     TypeInfo m_next;
94 }
95
96 class TypeInfo_Array : TypeInfo
97 {
98     TypeInfo value;
99 }
100
101 class TypeInfo_StaticArray : TypeInfo
102 {
103     TypeInfo value;
104     size_t   len;
105 }
106
107 class TypeInfo_AssociativeArray : TypeInfo
108 {
109     TypeInfo value;
110     TypeInfo key;
111     TypeInfo impl;
112 }
113
114 class TypeInfo_Function : TypeInfo
115 {
116     TypeInfo next;
117 }
118
119 class TypeInfo_Delegate : TypeInfo
120 {
121     TypeInfo next;
122 }
123
124 class TypeInfo_Class : TypeInfo
125 {
126     @property TypeInfo_Class info() { return this; }
127     @property TypeInfo typeinfo() { return this; }
128
129     byte[]      init;   // class static initializer
130     string      name;   // class name
131     void*[]     vtbl;   // virtual function pointer table
132     Interface[] interfaces;
133     TypeInfo_Class   base;
134     void*       destructor;
135     void function(Object) classInvariant;
136     uint        m_flags;
137     //  1:      // is IUnknown or is derived from IUnknown
138     //  2:      // has no possible pointers into GC memory
139     //  4:      // has offTi[] member
140     //  8:      // has constructors
141     // 16:      // has xgetMembers member
142     // 32:      // has typeinfo member
143     void*       deallocator;
144     OffsetTypeInfo[] m_offTi;
145     void*       defaultConstructor;
146     const(MemberInfo[]) function(string) xgetMembers;
147
148     static TypeInfo_Class find(in char[] classname);
149     Object create();
150     const(MemberInfo[]) getMembers(in char[] classname);
151 }
152
153 alias TypeInfo_Class ClassInfo;
154
155 class TypeInfo_Interface : TypeInfo
156 {
157     ClassInfo info;
158 }
159
160 class TypeInfo_Struct : TypeInfo
161 {
162     string name;
163     void[] m_init;
164
165     uint function(in void*)               xtoHash;
166     equals_t function(in void*, in void*) xopEquals;
167     int function(in void*, in void*)      xopCmp;
168     string function(in void*)             xtoString;
169
170     uint m_flags;
171
172     const(MemberInfo[]) function(in char[]) xgetMembers;
173     void function(void*)                    xdtor;
174     void function(void*)                    xpostblit;
175
176     uint m_align;
177
178     version (X86_64)
179     {
180         TypeInfo m_arg1;
181         TypeInfo m_arg2;
182     }
183 }
184
185 class TypeInfo_Tuple : TypeInfo
186 {
187     TypeInfo[]  elements;
188 }
189
190 class TypeInfo_Const : TypeInfo
191 {
192     TypeInfo next;
193 }
194
195 class TypeInfo_Invariant : TypeInfo_Const
196 {
197
198 }
199
200 class TypeInfo_Shared : TypeInfo_Const
201 {
202 }
203
204 class TypeInfo_Inout : TypeInfo_Const
205 {
206 }
207
208 abstract class MemberInfo
209 {
210     string name();
211 }
212
213 class MemberInfo_field : MemberInfo
214 {
215     this(string name, TypeInfo ti, size_t offset);
216
217     override string name();
218     TypeInfo typeInfo();
219     size_t offset();
220 }
221
222 class MemberInfo_function : MemberInfo
223 {
224     enum
225     {
226         Virtual = 1,
227         Member  = 2,
228         Static  = 4,
229     }
230
231     this(string name, TypeInfo ti, void* fp, uint flags);
232
233     override string name();
234     TypeInfo typeInfo();
235     void* fp();
236     uint flags();
237 }
238
239 struct ModuleInfo
240 {
241     struct New
242     {
243         uint flags;
244         uint index;
245     }
246
247     struct Old
248     {
249         string           name;
250         ModuleInfo*[]    importedModules;
251         TypeInfo_Class[] localClasses;
252         uint             flags;
253
254         void function() ctor;
255         void function() dtor;
256         void function() unitTest;
257         void* xgetMembers;
258         void function() ictor;
259         void function() tlsctor;
260         void function() tlsdtor;
261         uint index;
262         void*[1] reserved;
263     }
264
265     union
266     {
267         New n;
268         Old o;
269     }
270
271     @property bool isNew();
272     @property uint index();
273     @property void index(uint i);
274     @property uint flags();
275     @property void flags(uint f);
276     @property void function() tlsctor();
277     @property void function() tlsdtor();
278     @property void* xgetMembers();
279     @property void function() ctor();
280     @property void function() dtor();
281     @property void function() ictor();
282     @property void function() unitTest();
283     @property ModuleInfo*[] importedModules();
284     @property TypeInfo_Class[] localClasses();
285     @property string name();
286
287     static int opApply(scope int delegate(ref ModuleInfo*) dg);
288 }
289
290 ModuleInfo*[] _moduleinfo_tlsdtors;
291 uint          _moduleinfo_tlsdtors_i;
292
293 extern (C) void _moduleTlsCtor();
294 extern (C) void _moduleTlsDtor();
295
296 class Throwable : Object
297 {
298     interface TraceInfo
299     {
300         int opApply(scope int delegate(ref char[]));
301         int opApply(scope int delegate(ref size_t, ref char[]));
302         string toString();
303     }
304
305     string      msg;
306     string      file;
307     size_t      line;
308     TraceInfo   info;
309     Throwable   next;
310
311     this(string msg, Throwable next = null);
312     this(string msg, string file, size_t line, Throwable next = null);
313     override string toString();
314 }
315
316
317 class Exception : Throwable
318 {
319     this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null);
320     this(string msg, Throwable next, string file = __FILE__, size_t line = __LINE__);
321 }
322
323
324 class Error : Throwable
325 {
326     this(string msg, Throwable next, string file = __FILE__, size_t line = __LINE__);
327     this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null);
328     Throwable   bypassedException;
329 }
330
331 extern (C)
332 {
333     // from druntime/src/compiler/dmd/aaA.d
334
335     size_t _aaLen(void* p);
336     void*  _aaGet(void** pp, TypeInfo keyti, size_t valuesize, ...);
337     void*  _aaGetRvalue(void* p, TypeInfo keyti, size_t valuesize, ...);
338     void*  _aaIn(void* p, TypeInfo keyti);
339     void   _aaDel(void* p, TypeInfo keyti, ...);
340     void[] _aaValues(void* p, size_t keysize, size_t valuesize);
341     void[] _aaKeys(void* p, size_t keysize);
342     void*  _aaRehash(void** pp, TypeInfo keyti);
343
344     extern (D) typedef scope int delegate(void *) _dg_t;
345     int _aaApply(void* aa, size_t keysize, _dg_t dg);
346
347     extern (D) typedef scope int delegate(void *, void *) _dg2_t;
348     int _aaApply2(void* aa, size_t keysize, _dg2_t dg);
349
350     void* _d_assocarrayliteralT(TypeInfo_AssociativeArray ti, size_t length, ...);
351 }
352
353 struct AssociativeArray(Key, Value)
354 {
355     void* p;
356
357     size_t length() @property { return _aaLen(p); }
358
359     Value[Key] rehash() @property
360     {
361         auto p = _aaRehash(&p, typeid(Value[Key]));
362         return *cast(Value[Key]*)(&p);
363     }
364    
365     Value[] values() @property
366     {
367         auto a = _aaValues(p, Key.sizeof, Value.sizeof);
368         return *cast(Value[]*) &a;
369     }
370
371     Key[] keys() @property
372     {
373         auto a = _aaKeys(p, Key.sizeof);
374         return *cast(Key[]*) &a;
375     }
376
377     int opApply(scope int delegate(ref Key, ref Value) dg)
378     {
379         return _aaApply2(p, Key.sizeof, cast(_dg2_t)dg);
380     }
381
382     int opApply(scope int delegate(ref Value) dg)
383     {
384         return _aaApply(p, Key.sizeof, cast(_dg_t)dg);
385     }
386
387     int delegate(int delegate(ref Key) dg) byKey()
388     {
389         int foo(int delegate(ref Key) dg)
390         {
391             int byKeydg(ref Key key, ref Value value)
392             {
393                return dg(key);
394             }
395
396             return _aaApply2(p, Key.sizeof, cast(_dg2_t)&byKeydg);
397         }
398
399     return &foo;
400     }
401    
402     int delegate(int delegate(ref Value) dg) byValue()
403     {
404         return &opApply;
405     }
406
407     Value get(Key key, lazy Value defaultValue)
408     {
409         auto r = key in *cast(Value[Key]*)(&p);
410         return r ? *r : defaultValue;
411     }
412
413     static if (is(typeof({ Value[Key] r; r[Key.init] = Value.init; }())))
414         @property Value[Key] dup()
415         {
416             Value[Key] result;
417             foreach (k, v; this)
418             {
419                 result[k] = v;
420             }
421             return result;
422         }
423 }
424
425 unittest
426 {
427     auto a = [ 1:"one", 2:"two", 3:"three" ];
428     auto b = a.dup;
429     assert(b == [ 1:"one", 2:"two", 3:"three" ]);
430 }
431
432 void clear(T)(T obj) if (is(T == class))
433 {
434     if (!obj) return;
435     auto ci = obj.classinfo;
436     auto defaultCtor =
437         cast(void function(Object)) ci.defaultConstructor;
438     version(none) // enforce isn't available in druntime
439         _enforce(defaultCtor || (ci.flags & 8) == 0);
440     immutable size = ci.init.length;
441
442     auto ci2 = ci;
443     do
444     {
445         auto dtor = cast(void function(Object))ci2.destructor;
446         if (dtor)
447             dtor(obj);
448         ci2 = ci2.base;
449     } while (ci2)
450
451         auto buf = (cast(void*) obj)[0 .. size];
452     buf[] = ci.init;
453     if (defaultCtor)
454         defaultCtor(obj);
455 }
456
457 void clear(T)(ref T obj) if (is(T == struct))
458 {
459     static if (is(typeof(obj.__dtor())))
460     {
461         obj.__dtor();
462     }
463     auto buf = (cast(ubyte*) &obj)[0 .. T.sizeof];
464     auto init = cast(ubyte[])typeid(T).init();
465     if(init.ptr is null) // null ptr means initialize to 0s
466         buf[] = 0;
467     else
468         buf[] = init[];
469 }
470
471 void clear(T : U[n], U, size_t n)(ref T obj)
472 {
473     obj = T.init;
474 }
475
476 void clear(T)(ref T obj)
477 if (!is(T == struct) && !is(T == class) && !_isStaticArray!T)
478 {
479     obj = T.init;
480 }
481
482 template _isStaticArray(T : U[N], U, size_t N)
483 {
484     enum bool _isStaticArray = true;
485 }
486
487 template _isStaticArray(T)
488 {
489     enum bool _isStaticArray = false;
490 }
491
492 private
493 {
494     extern (C) void _d_arrayshrinkfit(TypeInfo ti, void[] arr);
495     extern (C) size_t _d_arraysetcapacity(TypeInfo ti, size_t newcapacity, void *arrptr);
496 }
497
498 @property size_t capacity(T)(T[] arr)
499 {
500     return _d_arraysetcapacity(typeid(T[]), 0, cast(void *)&arr);
501 }
502
503 size_t reserve(T)(ref T[] arr, size_t newcapacity)
504 {
505     return _d_arraysetcapacity(typeid(T[]), newcapacity, cast(void *)&arr);
506 }
507
508 void assumeSafeAppend(T)(T[] arr)
509 {
510     _d_arrayshrinkfit(typeid(T[]), *(cast(void[]*)&arr));
511 }
512
513 bool _ArrayEq(T1, T2)(T1[] a1, T2[] a2)
514 {
515     if (a1.length != a2.length)
516         return false;
517     foreach(i, a; a1)
518     {   if (a != a2[i])
519             return false;
520     }
521     return true;
522 }
Note: See TracBrowser for help on using the browser.