mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-07-22 07:05:22 +02:00
[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:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -27,7 +27,7 @@ private import typeinfo.ti_cdouble;
|
||||
|
||||
// cdouble[]
|
||||
|
||||
class TypeInfo_Ar : TypeInfo
|
||||
class TypeInfo_Ar : TypeInfo_Array
|
||||
{
|
||||
char[] toString() { return "cdouble[]"; }
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ private import typeinfo.ti_cfloat;
|
||||
|
||||
// cfloat[]
|
||||
|
||||
class TypeInfo_Aq : TypeInfo
|
||||
class TypeInfo_Aq : TypeInfo_Array
|
||||
{
|
||||
char[] toString() { return "cfloat[]"; }
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ private import typeinfo.ti_creal;
|
||||
|
||||
// creal[]
|
||||
|
||||
class TypeInfo_Ac : TypeInfo
|
||||
class TypeInfo_Ac : TypeInfo_Array
|
||||
{
|
||||
char[] toString() { return "creal[]"; }
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ private import typeinfo.ti_double;
|
||||
|
||||
// double[]
|
||||
|
||||
class TypeInfo_Ad : TypeInfo
|
||||
class TypeInfo_Ad : TypeInfo_Array
|
||||
{
|
||||
char[] toString() { return "double[]"; }
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ private import typeinfo.ti_float;
|
||||
|
||||
// float[]
|
||||
|
||||
class TypeInfo_Af : TypeInfo
|
||||
class TypeInfo_Af : TypeInfo_Array
|
||||
{
|
||||
char[] toString() { return "float[]"; }
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ private import util.string;
|
||||
|
||||
// byte[]
|
||||
|
||||
class TypeInfo_Ag : TypeInfo
|
||||
class TypeInfo_Ag : TypeInfo_Array
|
||||
{
|
||||
char[] toString() { return "byte[]"; }
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ private import tango.stdc.string;
|
||||
|
||||
// int[]
|
||||
|
||||
class TypeInfo_Ai : TypeInfo
|
||||
class TypeInfo_Ai : TypeInfo_Array
|
||||
{
|
||||
char[] toString() { return "int[]"; }
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ private import tango.stdc.string;
|
||||
|
||||
// long[]
|
||||
|
||||
class TypeInfo_Al : TypeInfo
|
||||
class TypeInfo_Al : TypeInfo_Array
|
||||
{
|
||||
char[] toString() { return "long[]"; }
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ private import typeinfo.ti_real;
|
||||
|
||||
// real[]
|
||||
|
||||
class TypeInfo_Ae : TypeInfo
|
||||
class TypeInfo_Ae : TypeInfo_Array
|
||||
{
|
||||
char[] toString() { return "real[]"; }
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ private import tango.stdc.string;
|
||||
|
||||
// short[]
|
||||
|
||||
class TypeInfo_As : TypeInfo
|
||||
class TypeInfo_As : TypeInfo_Array
|
||||
{
|
||||
char[] toString() { return "short[]"; }
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user