X-Git-Url: https://git.llucax.com/software/druntime.git/blobdiff_plain/5a07183e26b7ca151959629420a83f59af5339f3..ee7c028ebdd89ffc05410551c6e4812187049279:/src/compiler/dmd/object_.d diff --git a/src/compiler/dmd/object_.d b/src/compiler/dmd/object_.d index 3f9ddd2..7341118 100644 --- a/src/compiler/dmd/object_.d +++ b/src/compiler/dmd/object_.d @@ -39,10 +39,10 @@ module object; private { - import stdc.string; - import stdc.stdlib; + import core.stdc.string; + import core.stdc.stdlib; import util.string; - debug(PRINTF) import stdc.stdio; + debug(PRINTF) import core.stdc.stdio; extern (C) void onOutOfMemoryError(); extern (C) Object _d_newclass(ClassInfo ci); @@ -54,7 +54,7 @@ private //alias typeof(int.sizeof) size_t; //alias typeof(cast(void*)0 - cast(void*)0) ptrdiff_t; -version( X86_64 ) +version(X86_64) { alias ulong size_t; alias long ptrdiff_t; @@ -66,11 +66,11 @@ else } alias size_t hash_t; -alias int equals_t; +alias bool equals_t; -alias char[] string; -alias wchar[] wstring; -alias dchar[] dstring; +alias invariant(char)[] string; +alias invariant(wchar)[] wstring; +alias invariant(dchar)[] dstring; /** * All D class objects inherit from Object. @@ -108,8 +108,8 @@ class Object // BUG: this prevents a compacting GC from working, needs to be fixed //return cast(int)cast(void*)this - cast(int)cast(void*)o; - //throw new Exception("need opCmp for class " ~ this.classinfo.name); - return this !is o; + throw new Exception("need opCmp for class " ~ this.classinfo.name); + //return this !is o; } /** @@ -125,6 +125,23 @@ class Object void lock(); void unlock(); } + + /** + * Create instance of class specified by classname. + * The class must either have no constructors or have + * a default constructor. + * Returns: + * null if failed + */ + static Object factory(string classname) + { + auto ci = ClassInfo.find(classname); + if (ci) + { + return ci.create(); + } + return null; + } } /** @@ -160,9 +177,11 @@ class ClassInfo : Object // 2: // has no possible pointers into GC memory // 4: // has offTi[] member // 8: // has constructors + // 16: // has xgetMembers member void* deallocator; OffsetTypeInfo[] offTi; void function(Object) defaultConstructor; // default Constructor + const(MemberInfo[]) function(in char[]) xgetMembers; /** * Search all modules for ClassInfo corresponding to classname. @@ -197,6 +216,17 @@ class ClassInfo : Object } return o; } + + /** + * Search for all members with the name 'name'. + * If name[] is null, return all members. + */ + const(MemberInfo[]) getMembers(in char[] name) + { + if (flags & 16 && xgetMembers) + return xgetMembers(name); + return null; + } } /** @@ -216,15 +246,16 @@ struct OffsetTypeInfo */ class TypeInfo { - hash_t toHash() - { hash_t hash; + override hash_t toHash() + { + hash_t hash; foreach (char c; this.toString()) hash = hash * 9 + c; return hash; } - int opCmp(Object o) + override int opCmp(Object o) { if (this is o) return 0; @@ -234,7 +265,7 @@ class TypeInfo return dstrcmp(this.toString(), ti.toString()); } - equals_t opEquals(Object o) + override equals_t opEquals(Object o) { /* TypeInfo instances are singletons, but duplicates can exist * across DLL's. Therefore, comparing for a name match is @@ -250,7 +281,7 @@ class TypeInfo hash_t getHash(in void* p) { return cast(hash_t)p; } /// Compares two instances for equality. - equals_t equals(in void* p1, in void* p2) { return cast(int)(p1 == p2); } + equals_t equals(in void* p1, in void* p2) { return p1 == p2; } /// Compares two instances for <, ==, or >. int compare(in void* p1, in void* p2) { return 0; } @@ -263,11 +294,10 @@ class TypeInfo { size_t n = tsize(); for (size_t i = 0; i < n; i++) - { byte t; - - t = (cast(byte *)p1)[i]; - (cast(byte *)p1)[i] = (cast(byte *)p2)[i]; - (cast(byte *)p2)[i] = t; + { + byte t = (cast(byte *)p1)[i]; + (cast(byte*)p1)[i] = (cast(byte*)p2)[i]; + (cast(byte*)p2)[i] = t; } } @@ -283,104 +313,110 @@ class TypeInfo /// Get type information on the contents of the type; null if not available OffsetTypeInfo[] offTi() { return null; } + /// Run the destructor on the object and all its sub-objects + void destroy(void* p) {} + /// Run the postblit on the object and all its sub-objects + void postblit(void* p) {} } class TypeInfo_Typedef : TypeInfo { - string toString() { return name; } - - equals_t opEquals(Object o) - { TypeInfo_Typedef c; + override string toString() { return name; } + override equals_t opEquals(Object o) + { + TypeInfo_Typedef c; return this is o || ((c = cast(TypeInfo_Typedef)o) !is null && this.name == c.name && this.base == c.base); } - hash_t getHash(in void* p) { return base.getHash(p); } - equals_t equals(in void* p1, in void* p2) { return base.equals(p1, p2); } - int compare(in void* p1, in void* p2) { return base.compare(p1, p2); } - size_t tsize() { return base.tsize(); } - void swap(void* p1, void* p2) { return base.swap(p1, p2); } + override hash_t getHash(in void* p) { return base.getHash(p); } + override equals_t equals(in void* p1, in void* p2) { return base.equals(p1, p2); } + override int compare(in void* p1, in void* p2) { return base.compare(p1, p2); } + override size_t tsize() { return base.tsize(); } + override void swap(void* p1, void* p2) { return base.swap(p1, p2); } - TypeInfo next() { return base.next(); } - uint flags() { return base.flags(); } - void[] init() { return m_init.length ? m_init : base.init(); } + override TypeInfo next() { return base.next(); } + override uint flags() { return base.flags(); } + override void[] init() { return m_init.length ? m_init : base.init(); } TypeInfo base; - string name; - void[] m_init; + string name; + void[] m_init; } class TypeInfo_Enum : TypeInfo_Typedef { + } class TypeInfo_Pointer : TypeInfo { - string toString() { return m_next.toString() ~ "*"; } - - equals_t opEquals(Object o) - { TypeInfo_Pointer c; + override string toString() { return m_next.toString() ~ "*"; } + override equals_t opEquals(Object o) + { + TypeInfo_Pointer c; return this is o || ((c = cast(TypeInfo_Pointer)o) !is null && this.m_next == c.m_next); } - hash_t getHash(in void* p) + override hash_t getHash(in void* p) { return cast(hash_t)*cast(void**)p; } - equals_t equals(in void* p1, in void* p2) + override equals_t equals(in void* p1, in void* p2) { - return cast(int)(*cast(void* *)p1 == *cast(void* *)p2); + return *cast(void**)p1 == *cast(void**)p2; } - int compare(in void* p1, in void* p2) + override int compare(in void* p1, in void* p2) { - if (*cast(void* *)p1 < *cast(void* *)p2) + if (*cast(void**)p1 < *cast(void**)p2) return -1; - else if (*cast(void* *)p1 > *cast(void* *)p2) + else if (*cast(void**)p1 > *cast(void**)p2) return 1; else return 0; } - size_t tsize() + override size_t tsize() { return (void*).sizeof; } - void swap(void* p1, void* p2) - { void* tmp; - tmp = *cast(void**)p1; + override void swap(void* p1, void* p2) + { + void* tmp = *cast(void**)p1; *cast(void**)p1 = *cast(void**)p2; *cast(void**)p2 = tmp; } - TypeInfo next() { return m_next; } - uint flags() { return 1; } + override TypeInfo next() { return m_next; } + override uint flags() { return 1; } TypeInfo m_next; } class TypeInfo_Array : TypeInfo { - string toString() { return value.toString() ~ "[]"; } - - equals_t opEquals(Object o) - { TypeInfo_Array c; + override string toString() { return value.toString() ~ "[]"; } + override equals_t opEquals(Object o) + { + TypeInfo_Array c; return this is o || ((c = cast(TypeInfo_Array)o) !is null && this.value == c.value); } - hash_t getHash(in void* p) - { size_t sz = value.tsize(); + override hash_t getHash(in void* p) + { + size_t sz = value.tsize(); hash_t hash = 0; void[] a = *cast(void[]*)p; for (size_t i = 0; i < a.length; i++) @@ -388,22 +424,22 @@ class TypeInfo_Array : TypeInfo return hash; } - equals_t equals(in void* p1, in void* p2) + override equals_t equals(in void* p1, in void* p2) { void[] a1 = *cast(void[]*)p1; void[] a2 = *cast(void[]*)p2; if (a1.length != a2.length) - return 0; + return false; size_t sz = value.tsize(); for (size_t i = 0; i < a1.length; i++) { if (!value.equals(a1.ptr + i * sz, a2.ptr + i * sz)) - return 0; + return false; } - return 1; + return true; } - int compare(in void* p1, in void* p2) + override int compare(in void* p1, in void* p2) { void[] a1 = *cast(void[]*)p1; void[] a2 = *cast(void[]*)p2; @@ -421,66 +457,67 @@ class TypeInfo_Array : TypeInfo return cast(int)a1.length - cast(int)a2.length; } - size_t tsize() + override size_t tsize() { return (void[]).sizeof; } - void swap(void* p1, void* p2) - { void[] tmp; - tmp = *cast(void[]*)p1; + override void swap(void* p1, void* p2) + { + void[] tmp = *cast(void[]*)p1; *cast(void[]*)p1 = *cast(void[]*)p2; *cast(void[]*)p2 = tmp; } TypeInfo value; - TypeInfo next() + override TypeInfo next() { return value; -} + } - uint flags() { return 1; } + override uint flags() { return 1; } } class TypeInfo_StaticArray : TypeInfo { - string toString() + override string toString() { - char [10] tmp = void; - return value.toString() ~ "[" ~ tmp.intToString(len) ~ "]"; + char[10] tmp = void; + return cast(string)(value.toString() ~ "[" ~ tmp.intToString(len) ~ "]"); } - equals_t opEquals(Object o) - { TypeInfo_StaticArray c; - + override equals_t opEquals(Object o) + { + TypeInfo_StaticArray c; return this is o || ((c = cast(TypeInfo_StaticArray)o) !is null && this.len == c.len && this.value == c.value); } - hash_t getHash(in void* p) - { size_t sz = value.tsize(); + override hash_t getHash(in void* p) + { + size_t sz = value.tsize(); hash_t hash = 0; for (size_t i = 0; i < len; i++) hash += value.getHash(p + i * sz); return hash; } - equals_t equals(in void* p1, in void* p2) + override equals_t equals(in void* p1, in void* p2) { size_t sz = value.tsize(); for (size_t u = 0; u < len; u++) { if (!value.equals(p1 + u * sz, p2 + u * sz)) - return 0; + return false; } - return 1; + return true; } - int compare(in void* p1, in void* p2) + override int compare(in void* p1, in void* p2) { size_t sz = value.tsize(); @@ -493,13 +530,14 @@ class TypeInfo_StaticArray : TypeInfo return 0; } - size_t tsize() + override size_t tsize() { return len * value.tsize(); } - void swap(void* p1, void* p2) - { void* tmp; + override void swap(void* p1, void* p2) + { + void* tmp; size_t sz = value.tsize(); ubyte[16] buffer; void* pbuffer; @@ -519,24 +557,45 @@ class TypeInfo_StaticArray : TypeInfo delete pbuffer; } - void[] init() { return value.init(); } - TypeInfo next() { return value; } - uint flags() { return value.flags(); } + override void[] init() { return value.init(); } + override TypeInfo next() { return value; } + override uint flags() { return value.flags(); } + + override void destroy(void* p) + { + auto sz = value.tsize(); + p += sz * len; + foreach (i; 0 .. len) + { + p -= sz; + value.destroy(p); + } + } + + override void postblit(void* p) + { + auto sz = value.tsize(); + foreach (i; 0 .. len) + { + value.postblit(p); + p += sz; + } + } TypeInfo value; - size_t len; + size_t len; } class TypeInfo_AssociativeArray : TypeInfo { - string toString() + override string toString() { - return next.toString() ~ "[" ~ key.toString() ~ "]"; + return cast(string)(next.toString() ~ "[" ~ key.toString() ~ "]"); } - equals_t opEquals(Object o) - { TypeInfo_AssociativeArray c; - + override equals_t opEquals(Object o) + { + TypeInfo_AssociativeArray c; return this is o || ((c = cast(TypeInfo_AssociativeArray)o) !is null && this.key == c.key && @@ -545,13 +604,13 @@ class TypeInfo_AssociativeArray : TypeInfo // BUG: need to add the rest of the functions - size_t tsize() + override size_t tsize() { return (char[int]).sizeof; } - TypeInfo next() { return value; } - uint flags() { return 1; } + override TypeInfo next() { return value; } + override uint flags() { return 1; } TypeInfo value; TypeInfo key; @@ -559,14 +618,14 @@ class TypeInfo_AssociativeArray : TypeInfo class TypeInfo_Function : TypeInfo { - string toString() + override string toString() { - return next.toString() ~ "()"; + return cast(string)(next.toString() ~ "()"); } - equals_t opEquals(Object o) - { TypeInfo_Function c; - + override equals_t opEquals(Object o) + { + TypeInfo_Function c; return this is o || ((c = cast(TypeInfo_Function)o) !is null && this.next == c.next); @@ -574,7 +633,7 @@ class TypeInfo_Function : TypeInfo // BUG: need to add the rest of the functions - size_t tsize() + override size_t tsize() { return 0; // no size for functions } @@ -584,14 +643,14 @@ class TypeInfo_Function : TypeInfo class TypeInfo_Delegate : TypeInfo { - string toString() + override string toString() { - return next.toString() ~ " delegate()"; + return cast(string)(next.toString() ~ " delegate()"); } - equals_t opEquals(Object o) - { TypeInfo_Delegate c; - + override equals_t opEquals(Object o) + { + TypeInfo_Delegate c; return this is o || ((c = cast(TypeInfo_Delegate)o) !is null && this.next == c.next); @@ -599,35 +658,36 @@ class TypeInfo_Delegate : TypeInfo // BUG: need to add the rest of the functions - size_t tsize() - { alias int delegate() dg; + override size_t tsize() + { + alias int delegate() dg; return dg.sizeof; } - uint flags() { return 1; } + override uint flags() { return 1; } TypeInfo next; } class TypeInfo_Class : TypeInfo { - string toString() { return info.name; } - - equals_t opEquals(Object o) - { TypeInfo_Class c; + override string toString() { return info.name; } + override equals_t opEquals(Object o) + { + TypeInfo_Class c; return this is o || ((c = cast(TypeInfo_Class)o) !is null && this.info.name == c.classinfo.name); } - hash_t getHash(in void* p) + override hash_t getHash(in void* p) { Object o = *cast(Object*)p; return o ? o.toHash() : 0; } - equals_t equals(in void* p1, in void* p2) + override equals_t equals(in void* p1, in void* p2) { Object o1 = *cast(Object*)p1; Object o2 = *cast(Object*)p2; @@ -635,7 +695,7 @@ class TypeInfo_Class : TypeInfo return (o1 is o2) || (o1 && o1.opEquals(o2)); } - int compare(in void* p1, in void* p2) + override int compare(in void* p1, in void* p2) { Object o1 = *cast(Object*)p1; Object o2 = *cast(Object*)p2; @@ -645,7 +705,8 @@ class TypeInfo_Class : TypeInfo if (o1 !is o2) { if (o1) - { if (!o2) + { + if (!o2) c = 1; else c = o1.opCmp(o2); @@ -656,14 +717,14 @@ class TypeInfo_Class : TypeInfo return c; } - size_t tsize() + override size_t tsize() { return Object.sizeof; } - uint flags() { return 1; } + override uint flags() { return 1; } - OffsetTypeInfo[] offTi() + override OffsetTypeInfo[] offTi() { return (info.flags & 4) ? info.offTi : null; } @@ -673,17 +734,17 @@ class TypeInfo_Class : TypeInfo class TypeInfo_Interface : TypeInfo { - string toString() { return info.name; } - - equals_t opEquals(Object o) - { TypeInfo_Interface c; + override string toString() { return info.name; } + override equals_t opEquals(Object o) + { + TypeInfo_Interface c; return this is o || ((c = cast(TypeInfo_Interface)o) !is null && this.info.name == c.classinfo.name); } - hash_t getHash(in void* p) + override hash_t getHash(in void* p) { Interface* pi = **cast(Interface ***)*cast(void**)p; Object o = cast(Object)(*cast(void**)p - pi.offset); @@ -691,7 +752,7 @@ class TypeInfo_Interface : TypeInfo return o.toHash(); } - equals_t equals(in void* p1, in void* p2) + override equals_t equals(in void* p1, in void* p2) { Interface* pi = **cast(Interface ***)*cast(void**)p1; Object o1 = cast(Object)(*cast(void**)p1 - pi.offset); @@ -701,7 +762,7 @@ class TypeInfo_Interface : TypeInfo return o1 == o2 || (o1 && o1.opCmp(o2) == 0); } - int compare(in void* p1, in void* p2) + override int compare(in void* p1, in void* p2) { Interface* pi = **cast(Interface ***)*cast(void**)p1; Object o1 = cast(Object)(*cast(void**)p1 - pi.offset); @@ -713,7 +774,8 @@ class TypeInfo_Interface : TypeInfo if (o1 != o2) { if (o1) - { if (!o2) + { + if (!o2) c = 1; else c = o1.opCmp(o2); @@ -724,116 +786,131 @@ class TypeInfo_Interface : TypeInfo return c; } - size_t tsize() + override size_t tsize() { return Object.sizeof; } - uint flags() { return 1; } + override uint flags() { return 1; } ClassInfo info; } class TypeInfo_Struct : TypeInfo { - string toString() { return name; } - - equals_t opEquals(Object o) - { TypeInfo_Struct s; + override string toString() { return name; } + override equals_t opEquals(Object o) + { + TypeInfo_Struct s; return this is o || ((s = cast(TypeInfo_Struct)o) !is null && this.name == s.name && this.init.length == s.init.length); } - hash_t getHash(in void* p) - { hash_t h; - + override hash_t getHash(in void* p) + { assert(p); if (xtoHash) - { debug(PRINTF) printf("getHash() using xtoHash\n"); - h = (*xtoHash)(p); + { + debug(PRINTF) printf("getHash() using xtoHash\n"); + return (*xtoHash)(p); } else { + hash_t h; debug(PRINTF) printf("getHash() using default hash\n"); // A sorry hash algorithm. // Should use the one for strings. // BUG: relies on the GC not moving objects + auto q = cast(const(ubyte)*)p; for (size_t i = 0; i < init.length; i++) - { h = h * 9 + *cast(ubyte*)p; - p++; + { + h = h * 9 + *q; + q++; } + return h; } - return h; } - equals_t equals(in void* p1, in void* p2) - { int c; - + override equals_t equals(in void* p1, in void* p2) + { if (p1 == p2) - c = 1; + return true; else if (!p1 || !p2) - c = 0; + return false; else if (xopEquals) - c = (*xopEquals)(p1, p2); + return (*xopEquals)(p1, p2); else // BUG: relies on the GC not moving objects - c = (memcmp(p1, p2, init.length) == 0); - return c; + return memcmp(p1, p2, init.length) == 0; } - int compare(in void* p1, in void* p2) + override int compare(in void* p1, in void* p2) { - int c = 0; - // Regard null references as always being "less than" if (p1 != p2) { if (p1) - { if (!p2) - c = 1; + { + if (!p2) + return true; else if (xopCmp) - c = (*xopCmp)(p2, p1); + return (*xopCmp)(p2, p1); else // BUG: relies on the GC not moving objects - c = memcmp(p1, p2, init.length); + return memcmp(p1, p2, init.length); } else - c = -1; + return -1; } - return c; + return 0; } - size_t tsize() + override size_t tsize() { return init.length; } - void[] init() { return m_init; } + override void[] init() { return m_init; } - uint flags() { return m_flags; } + override uint flags() { return m_flags; } + + override void destroy(void* p) + { + if (xdtor) + (*xdtor)(p); + } + + override void postblit(void* p) + { + if (xpostblit) + (*xpostblit)(p); + } string name; void[] m_init; // initializer; init.ptr == null if 0 initialize - hash_t function(void*) xtoHash; - int function(void*,void*) xopEquals; - int function(void*,void*) xopCmp; - char[] function(void*) xtoString; + hash_t function(in void*) xtoHash; + equals_t function(in void*, in void*) xopEquals; + int function(in void*, in void*) xopCmp; + char[] function(in void*) xtoString; uint m_flags; + + const(MemberInfo[]) function(in char[]) xgetMembers; + void function(void*) xdtor; + void function(void*) xpostblit; } class TypeInfo_Tuple : TypeInfo { TypeInfo[] elements; - string toString() + override string toString() { - char[] s; - s = "("; + string s = "("; foreach (i, element; elements) { if (i) @@ -844,7 +921,7 @@ class TypeInfo_Tuple : TypeInfo return s; } - equals_t opEquals(Object o) + override equals_t opEquals(Object o) { if (this is o) return true; @@ -862,59 +939,142 @@ class TypeInfo_Tuple : TypeInfo return false; } - hash_t getHash(in void* p) + override hash_t getHash(in void* p) { assert(0); } - equals_t equals(in void* p1, in void* p2) + override equals_t equals(in void* p1, in void* p2) { assert(0); } - int compare(in void* p1, in void* p2) + override int compare(in void* p1, in void* p2) { assert(0); } - size_t tsize() + override size_t tsize() { assert(0); } - void swap(void* p1, void* p2) + override void swap(void* p1, void* p2) { assert(0); } + + override void destroy(void* p) + { + assert(0); + } + + override void postblit(void* p) + { + assert(0); + } +} + +class TypeInfo_Const : TypeInfo +{ + override string toString() + { + return cast(string) ("const(" ~ base.toString() ~ ")"); + } + + override equals_t opEquals(Object o) { return base.opEquals(o); } + override hash_t getHash(in void *p) { return base.getHash(p); } + override equals_t equals(in void *p1, in void *p2) { return base.equals(p1, p2); } + override int compare(in void *p1, in void *p2) { return base.compare(p1, p2); } + override size_t tsize() { return base.tsize(); } + override void swap(void *p1, void *p2) { return base.swap(p1, p2); } + + override TypeInfo next() { return base.next(); } + override uint flags() { return base.flags(); } + override void[] init() { return base.init(); } + + TypeInfo base; +} + +class TypeInfo_Invariant : TypeInfo_Const +{ + override string toString() + { + return cast(string) ("invariant(" ~ base.toString() ~ ")"); + } +} + +abstract class MemberInfo +{ + string name(); +} + +class MemberInfo_field : MemberInfo +{ + this(string name, TypeInfo ti, size_t offset) + { + m_name = name; + m_typeinfo = ti; + m_offset = offset; + } + + override string name() { return m_name; } + TypeInfo typeInfo() { return m_typeinfo; } + size_t offset() { return m_offset; } + + string m_name; + TypeInfo m_typeinfo; + size_t m_offset; +} + +class MemberInfo_function : MemberInfo +{ + this(string name, TypeInfo ti, void* fp, uint flags) + { + m_name = name; + m_typeinfo = ti; + m_fp = fp; + m_flags = flags; + } + + override string name() { return m_name; } + TypeInfo typeInfo() { return m_typeinfo; } + void* fp() { return m_fp; } + uint flags() { return m_flags; } + + string m_name; + TypeInfo m_typeinfo; + void* m_fp; + uint m_flags; } /////////////////////////////////////////////////////////////////////////////// -// Exception +// Throwable /////////////////////////////////////////////////////////////////////////////// -class Exception : Object +class Throwable : Object { interface TraceInfo { - int opApply( int delegate( inout char[] ) ); + int opApply(int delegate(inout char[])); } - char[] msg; - char[] file; + string msg; + string file; size_t line; TraceInfo info; - Exception next; + Throwable next; - this( char[] msg, Exception next = null ) + this(string msg, Throwable next = null) { this.msg = msg; this.next = next; this.info = traceContext(); } - this( char[] msg, char[] file, size_t line, Exception next = null ) + this(string msg, string file, size_t line, Throwable next = null) { this(msg, next); this.file = file; @@ -922,14 +1082,36 @@ class Exception : Object this.info = traceContext(); } - string toString() + override string toString() { - return msg; + char[10] tmp = void; + char[] buf; + + for (Throwable e = this; e !is null; e = e.next) + { + if (e.file) + { + buf ~= e.classinfo.name ~ "@" ~ e.file ~ "(" ~ tmp.intToString(e.line) ~ "): " ~ e.msg; + } + else + { + buf ~= e.classinfo.name ~ ": " ~ e.msg; + } + if (e.info) + { + buf ~= "\n----------------"; + foreach (t; e.info) + buf ~= "\n" ~ t; + } + if (e.next) + buf ~= "\n"; + } + return cast(string) buf; } } -alias Exception.TraceInfo function( void* ptr = null ) TraceHandler; +alias Throwable.TraceInfo function(void* ptr = null) TraceHandler; private TraceHandler traceHandler = null; @@ -939,14 +1121,14 @@ private TraceHandler traceHandler = null; * Params: * h = The new trace handler. Set to null to use the default handler. */ -extern (C) void rt_setTraceHandler( TraceHandler h ) +extern (C) void rt_setTraceHandler(TraceHandler h) { traceHandler = h; } /** - * This function will be called when an Exception is constructed. The + * This function will be called when an exception is constructed. The * user-supplied trace handler will be called if one has been supplied, * otherwise no trace will be generated. * @@ -959,11 +1141,39 @@ extern (C) void rt_setTraceHandler( TraceHandler h ) * An object describing the current calling context or null if no handler is * supplied. */ -Exception.TraceInfo traceContext( void* ptr = null ) +Throwable.TraceInfo traceContext(void* ptr = null) { - if( traceHandler is null ) + if (traceHandler is null) return null; - return traceHandler( ptr ); + return traceHandler(ptr); +} + + +class Exception : Throwable +{ + this(string msg, Throwable next = null) + { + super(msg, next); + } + + this(string msg, string file, size_t line, Throwable next = null) + { + super(msg, file, line, next); + } +} + + +class Error : Throwable +{ + this(string msg, Throwable next = null) + { + super(msg, next); + } + + this(string msg, string file, size_t line, Throwable next = null) + { + super(msg, file, line, next); + } } @@ -997,14 +1207,14 @@ class ModuleInfo void function() ictor; // module static constructor (order independent) - static int opApply( int delegate( inout ModuleInfo ) dg ) + static int opApply(int delegate(inout ModuleInfo) dg) { int ret = 0; - foreach( m; _moduleinfo_array ) + foreach (m; _moduleinfo_array) { - ret = dg( m ); - if( ret ) + ret = dg(m); + if (ret) break; } return ret; @@ -1102,7 +1312,7 @@ void _moduleCtor2(ModuleInfo[] mi, int skip) if (m.flags & MIctorstart) { if (skip || m.flags & MIstandalone) continue; - throw new Exception( "Cyclic dependency in module " ~ m.name ); + throw new Exception("Cyclic dependency in module " ~ m.name); } m.flags |= MIctorstart;