From b29ba2914571d42232476d23c06a9f79291f7646 Mon Sep 17 00:00:00 2001 From: sean Date: Tue, 23 Sep 2008 03:29:18 +0000 Subject: [PATCH] Applied all D2 changes to trunk. It should now be a fully functional D2 runtime. git-svn-id: http://svn.dsource.org/projects/druntime/trunk@10 4a9d5153-6564-4b3f-b5e1-7e8e9dac548f --- import/object.di | 58 ++++++++++- import/stdc/stdio.d | 32 +++--- src/compiler/dmd/arrayassign.d | 180 +++++++++++++++++++++++++++++++++ src/compiler/dmd/dmain2.d | 5 + src/compiler/dmd/object_.d | 144 +++++++++++++++++++++++++- src/compiler/dmd/posix.mak | 1 + src/compiler/dmd/win32.mak | 1 + src/gc/basic/gcbits.d | 2 +- src/gc/basic/gcx.d | 6 +- 9 files changed, 401 insertions(+), 28 deletions(-) create mode 100644 src/compiler/dmd/arrayassign.d diff --git a/import/object.di b/import/object.di index 7400468..1ad5c94 100644 --- a/import/object.di +++ b/import/object.di @@ -6,9 +6,9 @@ alias typeof(cast(void*)0 - cast(void*)0) ptrdiff_t; alias size_t hash_t; alias int equals_t; -alias char[] string; -alias wchar[] wstring; -alias dchar[] dstring; +alias invariant(char)[] string; +alias invariant(wchar)[] wstring; +alias invariant(dchar)[] dstring; class Object { @@ -45,12 +45,15 @@ 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* defaultConstructor; + const(MemberInfo[]) function(string) xgetMembers; static ClassInfo find(in char[] classname); Object create(); + const(MemberInfo[]) getMembers(in char[] classname); } struct OffsetTypeInfo @@ -71,6 +74,8 @@ class TypeInfo uint flags(); // 1: // has possible pointers into GC memory OffsetTypeInfo[] offTi(); + void destroy(void* p); + void postblit(void* p); } class TypeInfo_Typedef : TypeInfo @@ -82,6 +87,7 @@ class TypeInfo_Typedef : TypeInfo class TypeInfo_Enum : TypeInfo_Typedef { + } class TypeInfo_Pointer : TypeInfo @@ -138,6 +144,9 @@ class TypeInfo_Struct : TypeInfo uint m_flags; + const(MemberInfo[]) function(in char[]) xgetMembers; + void function(void*) xdtor; + void function(void*) xpostblit; } class TypeInfo_Tuple : TypeInfo @@ -145,6 +154,47 @@ class TypeInfo_Tuple : TypeInfo TypeInfo[] elements; } +class TypeInfo_Const : TypeInfo +{ + TypeInfo next; +} + +class TypeInfo_Invariant : TypeInfo_Const +{ + +} + +abstract class MemberInfo +{ + string name(); +} + +class MemberInfo_field : MemberInfo +{ + this(string name, TypeInfo ti, size_t offset); + + override string name(); + TypeInfo typeInfo(); + size_t offset(); +} + +class MemberInfo_function : MemberInfo +{ + enum + { + Virtual = 1, + Member = 2, + Static = 4, + } + + this(string name, TypeInfo ti, void* fp, uint flags); + + override string name(); + TypeInfo typeInfo(); + void* fp(); + uint flags(); +} + class ModuleInfo { string name; @@ -163,7 +213,7 @@ class Exception : Object { interface TraceInfo { - int opApply( int delegate( inout char[] ) ); + int opApply( int delegate(inout char[]) ); string toString(); } diff --git a/import/stdc/stdio.d b/import/stdc/stdio.d index f988a41..bb6441d 100644 --- a/import/stdc/stdio.d +++ b/import/stdc/stdio.d @@ -234,11 +234,11 @@ version( Windows ) { extern FILE[_NFILE]* _imp___iob; - const FILE* stdin; - const FILE* stdout; - const FILE* stderr; - const FILE* stdaux; - const FILE* stdprn; + auto FILE* stdin; + auto FILE* stdout; + auto FILE* stderr; + auto FILE* stdaux; + auto FILE* stdprn; static this() { @@ -253,11 +253,11 @@ version( Windows ) { extern FILE[_NFILE] _iob; - const FILE* stdin = &_iob[0]; - const FILE* stdout = &_iob[1]; - const FILE* stderr = &_iob[2]; - const FILE* stdaux = &_iob[3]; - const FILE* stdprn = &_iob[4]; + auto FILE* stdin = &_iob[0]; + auto FILE* stdout = &_iob[1]; + auto FILE* stderr = &_iob[2]; + auto FILE* stdaux = &_iob[3]; + auto FILE* stdprn = &_iob[4]; } } else version( linux ) @@ -279,9 +279,9 @@ else version( darwin ) extern FILE* __stdoutp; extern FILE* __stderrp; - const FILE* stdin; - const FILE* stdout; - const FILE* stderr; + auto FILE* stdin; + auto FILE* stdout; + auto FILE* stderr; static this() { @@ -294,9 +294,9 @@ else version( freebsd ) { extern FILE[3] __sF; - const FILE* stdin = &__sF[0]; - const FILE* stdout = &__sF[1]; - const FILE* stderr = &__sF[2]; + auto FILE* stdin = &__sF[0]; + auto FILE* stdout = &__sF[1]; + auto FILE* stderr = &__sF[2]; } else { diff --git a/src/compiler/dmd/arrayassign.d b/src/compiler/dmd/arrayassign.d new file mode 100644 index 0000000..d85af7e --- /dev/null +++ b/src/compiler/dmd/arrayassign.d @@ -0,0 +1,180 @@ +/** + * Part of the D programming language runtime library. + * http://www.digitalmars.com + * Written by Walter Bright + * Placed in the Public Domain + */ +module rt.arrayassign; + +private +{ + import util.string; + import stdc.string; + import stdc.stdlib; + debug(PRINTF) import stdc.stdio; +} + +/** + * Does array assignment (not construction) from another + * array of the same element type. + * ti is the element type. + * Handles overlapping copies. + */ +extern (C) void[] _d_arrayassign(TypeInfo ti, void[] from, void[] to) +{ + debug(PRINTF) printf("_d_arrayassign(from = %p,%d, to = %p,%d) size = %d\n", from.ptr, from.length, to.ptr, to.length, ti.tsize()); + + if (to.length != from.length) + { + char[10] tmp = void; + string msg = "lengths don't match for array copy,"c; + msg ~= tmp.intToString(to.length) ~ " = " ~ tmp.intToString(from.length); + throw new Exception(msg); + } + + auto element_size = ti.tsize(); + + /* Need a temporary buffer tmp[] big enough to hold one element + */ + void[16] buf = void; + void[] tmp; + if (element_size > buf.sizeof) + tmp = alloca(element_size)[0 .. element_size]; + else + tmp = buf; + + + if (to.ptr <= from.ptr) + { + foreach (i; 0 .. to.length) + { + void* pto = to.ptr + i * element_size; + void* pfrom = from.ptr + i * element_size; + memcpy(tmp.ptr, pto, element_size); + memcpy(pto, pfrom, element_size); + ti.postblit(pto); + ti.destroy(tmp.ptr); + } + } + else + { + for (int i = to.length; i--; ) + { + void* pto = to.ptr + i * element_size; + void* pfrom = from.ptr + i * element_size; + memcpy(tmp.ptr, pto, element_size); + memcpy(pto, pfrom, element_size); + ti.postblit(pto); + ti.destroy(tmp.ptr); + } + } + return to; +} + +/** + * Does array initialization (not assignment) from another + * array of the same element type. + * ti is the element type. + */ +extern (C) void[] _d_arrayctor(TypeInfo ti, void[] from, void[] to) +{ + debug(PRINTF) printf("_d_arrayctor(from = %p,%d, to = %p,%d) size = %d\n", from.ptr, from.length, to.ptr, to.length, ti.tsize()); + + if (to.length != from.length) + { + char[10] tmp = void; + string msg = "lengths don't match for array initialization,"c; + msg ~= tmp.intToString(to.length) ~ " = " ~ tmp.intToString(from.length); + throw new Exception(msg); + } + + auto element_size = ti.tsize(); + + int i; + try + { + for (i = 0; i < to.length; i++) + { + // Copy construction is defined as bit copy followed by postblit. + memcpy(to.ptr + i * element_size, from.ptr + i * element_size, element_size); + ti.postblit(to.ptr + i * element_size); + } + } + catch (Object o) + { + /* Destroy, in reverse order, what we've constructed so far + */ + while (i--) + { + ti.destroy(to.ptr + i * element_size); + } + + throw o; + } + return to; +} + + +/** + * Do assignment to an array. + * p[0 .. count] = value; + */ +extern (C) void* _d_arraysetassign(void* p, void* value, int count, TypeInfo ti) +{ + void* pstart = p; + + auto element_size = ti.tsize(); + + //Need a temporary buffer tmp[] big enough to hold one element + void[16] buf = void; + void[] tmp; + if (element_size > buf.sizeof) + { + tmp = alloca(element_size)[0 .. element_size]; + } + else + tmp = buf; + + foreach (i; 0 .. count) + { + memcpy(tmp.ptr, p, element_size); + memcpy(p, value, element_size); + ti.postblit(p); + ti.destroy(tmp.ptr); + p += element_size; + } + return pstart; +} + +/** + * Do construction of an array. + * ti[count] p = value; + */ +extern (C) void* _d_arraysetctor(void* p, void* value, int count, TypeInfo ti) +{ + void* pstart = p; + auto element_size = ti.tsize(); + + try + { + foreach (i; 0 .. count) + { + // Copy construction is defined as bit copy followed by postblit. + memcpy(p, value, element_size); + ti.postblit(p); + p += element_size; + } + } + catch (Object o) + { + // Destroy, in reverse order, what we've constructed so far + while (p > pstart) + { + p -= element_size; + ti.destroy(p); + } + + throw o; + } + return pstart; +} diff --git a/src/compiler/dmd/dmain2.d b/src/compiler/dmd/dmain2.d index 4285db8..4141920 100644 --- a/src/compiler/dmd/dmain2.d +++ b/src/compiler/dmd/dmain2.d @@ -74,6 +74,11 @@ extern (C) void _d_switch_error( string file, uint line ) onSwitchError( file, line ); } +extern (C) void _d_hidden_func() +{ + // TODO: Figure out what to do with this routine +} + bool _d_isHalting = false; extern (C) bool rt_isHalting() diff --git a/src/compiler/dmd/object_.d b/src/compiler/dmd/object_.d index 0ffa9fb..df5cfff 100644 --- a/src/compiler/dmd/object_.d +++ b/src/compiler/dmd/object_.d @@ -68,9 +68,9 @@ else alias size_t hash_t; alias int 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. @@ -160,9 +160,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 +199,16 @@ 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; + } } /** @@ -282,6 +294,10 @@ 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 @@ -526,6 +542,27 @@ class TypeInfo_StaticArray : TypeInfo 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; } @@ -768,7 +805,7 @@ class TypeInfo_Struct : TypeInfo // A sorry hash algorithm. // Should use the one for strings. // BUG: relies on the GC not moving objects - auto q = cast(ubyte*)p; + auto q = cast(const(ubyte)*)p; for (size_t i = 0; i < init.length; i++) { h = h * 9 + *q; @@ -821,6 +858,18 @@ class TypeInfo_Struct : TypeInfo 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 @@ -830,6 +879,10 @@ class TypeInfo_Struct : TypeInfo 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 @@ -891,6 +944,89 @@ class TypeInfo_Tuple : TypeInfo { 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; } diff --git a/src/compiler/dmd/posix.mak b/src/compiler/dmd/posix.mak index ee3b8fa..51762be 100644 --- a/src/compiler/dmd/posix.mak +++ b/src/compiler/dmd/posix.mak @@ -67,6 +67,7 @@ OBJ_BASE= \ aApplyR.o \ adi.o \ alloca.o \ + arrayassign.o \ arraybyte.o \ arraycast.o \ arraycat.o \ diff --git a/src/compiler/dmd/win32.mak b/src/compiler/dmd/win32.mak index 3ac7221..0314474 100644 --- a/src/compiler/dmd/win32.mak +++ b/src/compiler/dmd/win32.mak @@ -63,6 +63,7 @@ OBJ_BASE= \ aApply.obj \ aApplyR.obj \ adi.obj \ + arrayassign.obj \ arraybyte.obj \ arraycast.obj \ arraycat.obj \ diff --git a/src/gc/basic/gcbits.d b/src/gc/basic/gcbits.d index a9f1683..a3c3e96 100644 --- a/src/gc/basic/gcbits.d +++ b/src/gc/basic/gcbits.d @@ -66,7 +66,7 @@ struct GCBits } } - invariant + invariant() { if (data) { diff --git a/src/gc/basic/gcx.d b/src/gc/basic/gcx.d index 0270dd5..15296ac 100644 --- a/src/gc/basic/gcx.d +++ b/src/gc/basic/gcx.d @@ -261,7 +261,7 @@ class GC } - invariant + invariant() { if (gcx) { @@ -1471,7 +1471,7 @@ struct Gcx void Invariant() { } - invariant + invariant() { if (inited) { @@ -2807,7 +2807,7 @@ struct Pool void Invariant() { } - invariant + invariant() { //mark.Invariant(); //scan.Invariant(); -- 2.43.0