Applied all D2 changes to trunk. It should now be a fully functional D2 runtime.

This commit is contained in:
Sean Kelly 2008-09-23 03:29:18 +00:00
parent 1ff99272c7
commit e5e25ae17f
9 changed files with 401 additions and 28 deletions

View file

@ -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();
}

View file

@ -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
{

View file

@ -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;
}

View file

@ -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()

View file

@ -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;
}

View file

@ -67,6 +67,7 @@ OBJ_BASE= \
aApplyR.o \
adi.o \
alloca.o \
arrayassign.o \
arraybyte.o \
arraycast.o \
arraycat.o \

View file

@ -63,6 +63,7 @@ OBJ_BASE= \
aApply.obj \
aApplyR.obj \
adi.obj \
arrayassign.obj \
arraybyte.obj \
arraycast.obj \
arraycat.obj \

View file

@ -66,7 +66,7 @@ struct GCBits
}
}
invariant
invariant()
{
if (data)
{

View file

@ -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();