[svn r229] Updated the object.d implementation to the latest Tango.

Fixed a bunch of the built-in typeinfos for arrays, they did not inherit TypeInfo_Array.
Applied patch to tango/text/convert/Layout.d by fvbommel, closes #47 .
Cleaned up some type code.
Replaced uses of llvm::Type with LLType (a typedef), same for Value and Constant.
Fixed a few cases where typeinfo for user structs could be emitted multiple times, seems to still be some cases of this :/
This commit is contained in:
Tomas Lindquist Olsen
2008-05-30 19:32:04 +02:00
parent 0b479b5749
commit b4bb3aaec4
40 changed files with 1219 additions and 1136 deletions

View File

@@ -37,11 +37,11 @@
module object;
//debug=PRINTF;
//debug=PRINTF
private
{
import tango.stdc.string; // : memcmp, memcpy;
import tango.stdc.string; // : memcmp, memcpy, memmove;
import tango.stdc.stdlib; // : calloc, realloc, free;
import util.string;
debug(PRINTF) import tango.stdc.stdio; // : printf;
@@ -126,7 +126,8 @@ class Object
/**
* Information about an interface.
* A pointer to this appears as the first entry in the interface's vtbl[].
* When an object is accessed via an interface, an Interface* appears as the
* first entry in its vtbl.
*/
struct Interface
{
@@ -436,7 +437,7 @@ class TypeInfo_Array : TypeInfo
TypeInfo next()
{
return value;
}
}
uint flags() { return 1; }
}
@@ -623,8 +624,7 @@ class TypeInfo_Class : TypeInfo
hash_t getHash(void *p)
{
Object o = *cast(Object*)p;
assert(o);
return o.toHash();
return o ? o.toHash() : 0;
}
int equals(void *p1, void *p2)
@@ -888,24 +888,38 @@ class TypeInfo_Tuple : TypeInfo
}
}
////////////////////////////////////////////////////////////////////////////////
// Exception
////////////////////////////////////////////////////////////////////////////////
class Exception : Object
{
interface TraceInfo
{
int opApply( int delegate( inout char[] ) );
}
char[] msg;
char[] file;
size_t line;
TraceInfo info;
Exception next;
this(char[] msg, Exception next = null)
this( char[] msg, Exception next = null )
{
this.msg = msg;
this.next = next;
this.info = traceContext();
}
this(char[] msg, char[] file, size_t line, Exception next = null)
this( char[] msg, char[] file, size_t line, Exception next = null )
{
this(msg, next);
this.file = file;
this.line = line;
this.info = traceContext();
}
char[] toString()
@@ -915,6 +929,44 @@ class Exception : Object
}
alias Exception.TraceInfo function( void* ptr = null ) TraceHandler;
private TraceHandler traceHandler = null;
/**
* Overrides the default trace hander with a user-supplied version.
*
* Params:
* h = The new trace handler. Set to null to use the default handler.
*/
extern (C) void rt_setTraceHandler( TraceHandler h )
{
traceHandler = h;
}
/**
* 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.
*
* Params:
* ptr = A pointer to the location from which to generate the trace, or null
* if the trace should be generated from within the trace handler
* itself.
*
* Returns:
* An object describing the current calling context or null if no handler is
* supplied.
*/
Exception.TraceInfo traceContext( void* ptr = null )
{
if( traceHandler is null )
return null;
return traceHandler( ptr );
}
////////////////////////////////////////////////////////////////////////////////
// ModuleInfo
////////////////////////////////////////////////////////////////////////////////
@@ -1094,11 +1146,20 @@ extern (C) void _moduleDtor()
// Monitor
////////////////////////////////////////////////////////////////////////////////
alias Object.Monitor IMonitor;
alias Object.Monitor IMonitor;
alias void delegate(Object) DEvent;
// NOTE: The dtor callback feature is only supported for monitors that are not
// supplied by the user. The assumption is that any object with a user-
// supplied monitor may have special storage or lifetime requirements and
// that as a result, storing references to local objects within Monitor
// may not be safe or desirable. Thus, devt is only valid if impl is
// null.
struct Monitor
{
IMonitor impl;
/* internal */
DEvent[] devt;
/* stuff */
}
@@ -1126,6 +1187,7 @@ extern (C) void _d_monitordelete(Object h, bool det)
IMonitor i = m.impl;
if (i is null)
{
_d_monitor_devt(m, h);
_d_monitor_destroy(h);
setMonitor(h, null);
return;
@@ -1168,3 +1230,71 @@ extern (C) void _d_monitorexit(Object h)
}
i.unlock();
}
extern (C) void _d_monitor_devt(Monitor* m, Object h)
{
if (m.devt.length)
{
DEvent[] devt;
synchronized (h)
{
devt = m.devt;
m.devt = null;
}
foreach (v; devt)
{
if (v)
v(h);
}
free(devt.ptr);
}
}
extern (C) void rt_attachDisposeEvent(Object h, DEvent e)
{
synchronized (h)
{
Monitor* m = getMonitor(h);
assert(m.impl is null);
foreach (inout v; m.devt)
{
if (v is null || v == e)
{
v = e;
return;
}
}
auto len = m.devt.length + 4; // grow by 4 elements
auto pos = m.devt.length; // insert position
auto p = realloc(m.devt.ptr, DEvent.sizeof * len);
if (!p)
onOutOfMemoryError();
m.devt = (cast(DEvent*)p)[0 .. len];
m.devt[pos+1 .. len] = null;
m.devt[pos] = e;
}
}
extern (C) void rt_detachDisposeEvent(Object h, DEvent e)
{
synchronized (h)
{
Monitor* m = getMonitor(h);
assert(m.impl is null);
foreach (p, v; m.devt)
{
if (v == e)
{
memmove(&m.devt[p],
&m.devt[p+1],
(m.devt.length - p - 1) * DEvent.sizeof);
m.devt[$ - 1] = null;
return;
}
}
}
}

View File

@@ -2,7 +2,7 @@ module typeinfo.ti_AC;
// Object[]
class TypeInfo_AC : TypeInfo
class TypeInfo_AC : TypeInfo_Array
{
hash_t getHash(void *p)
{ Object[] s = *cast(Object[]*)p;

View File

@@ -27,7 +27,7 @@ private import typeinfo.ti_cdouble;
// cdouble[]
class TypeInfo_Ar : TypeInfo
class TypeInfo_Ar : TypeInfo_Array
{
char[] toString() { return "cdouble[]"; }

View File

@@ -27,7 +27,7 @@ private import typeinfo.ti_cfloat;
// cfloat[]
class TypeInfo_Aq : TypeInfo
class TypeInfo_Aq : TypeInfo_Array
{
char[] toString() { return "cfloat[]"; }

View File

@@ -27,7 +27,7 @@ private import typeinfo.ti_creal;
// creal[]
class TypeInfo_Ac : TypeInfo
class TypeInfo_Ac : TypeInfo_Array
{
char[] toString() { return "creal[]"; }

View File

@@ -27,7 +27,7 @@ private import typeinfo.ti_double;
// double[]
class TypeInfo_Ad : TypeInfo
class TypeInfo_Ad : TypeInfo_Array
{
char[] toString() { return "double[]"; }

View File

@@ -27,7 +27,7 @@ private import typeinfo.ti_float;
// float[]
class TypeInfo_Af : TypeInfo
class TypeInfo_Af : TypeInfo_Array
{
char[] toString() { return "float[]"; }

View File

@@ -6,7 +6,7 @@ private import util.string;
// byte[]
class TypeInfo_Ag : TypeInfo
class TypeInfo_Ag : TypeInfo_Array
{
char[] toString() { return "byte[]"; }

View File

@@ -5,7 +5,7 @@ private import tango.stdc.string;
// int[]
class TypeInfo_Ai : TypeInfo
class TypeInfo_Ai : TypeInfo_Array
{
char[] toString() { return "int[]"; }

View File

@@ -5,7 +5,7 @@ private import tango.stdc.string;
// long[]
class TypeInfo_Al : TypeInfo
class TypeInfo_Al : TypeInfo_Array
{
char[] toString() { return "long[]"; }

View File

@@ -27,7 +27,7 @@ private import typeinfo.ti_real;
// real[]
class TypeInfo_Ae : TypeInfo
class TypeInfo_Ae : TypeInfo_Array
{
char[] toString() { return "real[]"; }

View File

@@ -5,7 +5,7 @@ private import tango.stdc.string;
// short[]
class TypeInfo_As : TypeInfo
class TypeInfo_As : TypeInfo_Array
{
char[] toString() { return "short[]"; }

View File

@@ -69,8 +69,15 @@ extern (C) void gc_term()
//
// NOTE: Due to popular demand, this has been re-enabled. It still has
// the problems mentioned above though, so I guess we'll see.
version(LLVMDC)
{
// currently crashes a lot
}
else
{
_gc.fullCollectNoStack(); // not really a 'collect all' -- still scans
// static data area, roots, and ranges.
}
_gc.Dtor();
}

View File

@@ -193,8 +193,26 @@ class Layout(T)
assert (formatStr, "null format specifier");
assert (arguments.length < 64, "too many args in Layout.convert");
version (X86_64)
version (LLVMDC)
{
static va_list get_va_arg(TypeInfo ti, ref va_list vp)
{
auto tisize = ti.tsize;
size_t size = tisize > size_t.sizeof ? size_t.sizeof : tisize;
va_list vptmp = cast(va_list)((cast(size_t)vp + size - 1) & ~(size - 1));
vp = vptmp + tisize;
return vptmp;
}
Arg[64] arglist = void;
foreach (i, arg; arguments)
{
arglist[i] = get_va_arg(arg, args);
}
}
else version (X86_64)
{
// code for x86-64 GDC
Arg[64] arglist = void;
int[64] intargs = void;
byte[64] byteargs = void;
@@ -265,25 +283,9 @@ class Layout(T)
}
}
}
else version (LLVMDC)
{
static va_list get_va_arg(TypeInfo ti, ref va_list vp)
{
auto tisize = ti.tsize;
size_t size = tisize > size_t.sizeof ? size_t.sizeof : tisize;
va_list vptmp = cast(va_list)((cast(size_t)vp + size - 1) & ~(size - 1));
vp = vptmp + tisize;
return vptmp;
}
Arg[64] arglist = void;
foreach (i, arg; arguments)
{
arglist[i] = get_va_arg(arg, args);
}
}
else
{
// code for DMD & x86 GDC (may also work on other 32-bit targets)
Arg[64] arglist = void;
foreach (i, arg; arguments)
{