538 changes: 271 additions & 267 deletions posix.mak

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions src/object.di
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,7 @@ class Object
static Object factory(string classname);
}

bool opEquals(const Object lhs, const Object rhs)
{
// A hack for the moment.
return opEquals(cast()lhs, cast()rhs);
}

bool opEquals(Object lhs, Object rhs)
auto opEquals(Object lhs, Object rhs)
{
// If aliased to the same object or both null => equal
if (lhs is rhs) return true;
Expand All @@ -77,6 +71,12 @@ bool opEquals(Object lhs, Object rhs)
return lhs.opEquals(rhs) && rhs.opEquals(lhs);
}

auto opEquals(const Object lhs, const Object rhs)
{
// A hack for the moment.
return opEquals(cast()lhs, cast()rhs);
}

void setSameMutex(shared Object ownee, shared Object owner);

struct Interface
Expand Down
742 changes: 275 additions & 467 deletions src/object_.d

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/rt/deh_win32.d
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module rt.deh_win32;
version (Win32):

import core.sys.windows.windows;
import rt.monitor_;
//import core.stdc.stdio;

version (D_InlineAsm_X86)
Expand Down
47 changes: 47 additions & 0 deletions src/rt/dmain2.d
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,53 @@ extern (C) int rt_term()
return 0;
}

/**********************************************
* Trace handler
*/
alias Throwable.TraceInfo function(void* ptr) TraceHandler;
private __gshared 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;
}

/**
* Return the current trace handler
*/
extern (C) TraceHandler rt_getTraceHandler()
{
return traceHandler;
}

/**
* 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.
*/
extern (C) Throwable.TraceInfo _d_traceContext(void* ptr = null)
{
if (traceHandler is null)
return null;
return traceHandler(ptr);
}

/***********************************
* Provide out-of-band access to the original C argc/argv
* passed to this program via main(argc,argv).
Expand Down
176 changes: 176 additions & 0 deletions src/rt/monitor_.d
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,188 @@ module rt.monitor_;

//debug=PRINTF;

///////////////////////////////////////////////////////////////////////////////
// Monitor
///////////////////////////////////////////////////////////////////////////////

// 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.

extern(C) void _d_setSameMutex(shared Object ownee, shared Object owner) nothrow
in
{
assert(ownee.__monitor is null);
}
body
{
auto m = cast(shared(Monitor)*) owner.__monitor;

if (m is null)
{
_d_monitor_create(cast(Object) owner);
m = cast(shared(Monitor)*) owner.__monitor;
}

auto i = m.impl;
if (i is null)
{
atomicOp!("+=")(m.refs, cast(size_t)1);
ownee.__monitor = owner.__monitor;
return;
}
// If m.impl is set (ie. if this is a user-created monitor), assume
// the monitor is garbage collected and simply copy the reference.
ownee.__monitor = owner.__monitor;
}

extern (C) void _d_monitordelete(Object h, bool det)
{
// det is true when the object is being destroyed deterministically (ie.
// when it is explicitly deleted or is a scope object whose time is up).
Monitor* m = getMonitor(h);

if (m !is null)
{
IMonitor i = m.impl;
if (i is null)
{
auto s = cast(shared(Monitor)*) m;
if(!atomicOp!("-=")(s.refs, cast(size_t) 1))
{
_d_monitor_devt(m, h);
_d_monitor_destroy(h);
setMonitor(h, null);
}
return;
}
// NOTE: Since a monitor can be shared via setSameMutex it isn't safe
// to explicitly delete user-created monitors--there's no
// refcount and it may have multiple owners.
/+
if (det && (cast(void*) i) !is (cast(void*) h))
{
destroy(i);
GC.free(cast(void*)i);
}
+/
setMonitor(h, null);
}
}

extern (C) void _d_monitorenter(Object h)
{
Monitor* m = getMonitor(h);

if (m is null)
{
_d_monitor_create(h);
m = getMonitor(h);
}

IMonitor i = m.impl;

if (i is null)
{
_d_monitor_lock(h);
return;
}
i.lock();
}

extern (C) void _d_monitorexit(Object h)
{
Monitor* m = getMonitor(h);
IMonitor i = m.impl;

if (i is null)
{
_d_monitor_unlock(h);
return;
}
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 (ref 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);
import core.exception : onOutOfMemoryError;
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;
}
}
}
}

nothrow:

private
{
debug(PRINTF) import core.stdc.stdio;
import core.stdc.stdlib;
import core.stdc.string;
import core.atomic;

version( linux )
{
Expand Down
146 changes: 72 additions & 74 deletions src/rt/util/string.d
Original file line number Diff line number Diff line change
@@ -1,76 +1,74 @@
/**
* String manipulation and comparison utilities.
*
* Copyright: Copyright Sean Kelly 2005 - 2009.
* License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
* Authors: Sean Kelly
*/
/**
* String manipulation and comparison utilities.
*
* Copyright: Copyright Sean Kelly 2005 - 2009.
* License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
* Authors: Sean Kelly
*/

/* Copyright Sean Kelly 2005 - 2009.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*/
module rt.util.string;

private import core.stdc.string;

@trusted:
pure:
nothrow:

alias UintStringBuff = char[10];
alias UlongStringBuff = char[20];

version(D_LP64)
alias SizeStringBuff = UlongStringBuff;
else
alias SizeStringBuff = UintStringBuff;

char[] uintToTempString(in uint val, char[] buff)
{ return val._unsignedToTempString(buff); }

char[] ulongToTempString(in ulong val, char[] buff)
{ return val._unsignedToTempString(buff); }

/* Copyright Sean Kelly 2005 - 2009.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*/
module rt.util.string;

private import core.stdc.string;

@trusted:
pure:
nothrow:

alias UintStringBuff = char[10];
alias UlongStringBuff = char[20];

version(D_LP64)
alias SizeStringBuff = UlongStringBuff;
else
alias SizeStringBuff = UintStringBuff;

char[] uintToTempString(size_t n)(in uint val, ref char[n] buff)
{ return val._unsignedToTempString(buff); }

char[] ulongToTempString(size_t n)(in ulong val, ref char[n] buff)
char[] sizeToTempString(in size_t val, char[] buff)
{ return val._unsignedToTempString(buff); }

version(D_LP64)
alias sizeToTempString = ulongToTempString;
else
alias sizeToTempString = uintToTempString;

private char[] _unsignedToTempString(T, size_t n)(in T val, ref char[n] buff)
if(is(T == uint) || is(T == ulong))
{
static assert(n >= (is(T == uint) ? 10 : 20), "Buffer is to small for `" ~ T.stringof ~ "`.");

char* p = buff.ptr + buff.length;
T k = val;
do
*--p = cast(char) (k % 10 + '0');
while(k /= 10);

return buff[p - buff.ptr .. $];
}

unittest
{
UlongStringBuff buff;
assert(1.uintToTempString(buff) == "1");
assert(12.ulongToTempString(buff) == "12");
assert(long.sizeof.sizeToTempString(buff) == "8");
assert(uint.max.uintToTempString(buff) == "4294967295");
assert(ulong.max.ulongToTempString(buff) == "18446744073709551615");
}


int dstrcmp( in char[] s1, in char[] s2 )
{
int ret = 0;
auto len = s1.length;
if( s2.length < len )
len = s2.length;
if( 0 != (ret = memcmp( s1.ptr, s2.ptr, len )) )
return ret;
return s1.length > s2.length ? 1 :
s1.length == s2.length ? 0 : -1;
}

private char[] _unsignedToTempString(T)(in T val, char[] buff)
if(is(T == uint) || is(T == ulong))
{
assert(buff.length >= (is(T == uint) ? 10 : 20), "Buffer is too small for `" ~ T.stringof ~ "`.");

char* p = buff.ptr + buff.length;
T k = val;
do
*--p = cast(char) (k % 10 + '0');
while(k /= 10);

return buff[p - buff.ptr .. $];
}

unittest
{
UlongStringBuff buff;
assert(1.uintToTempString(buff) == "1");
assert(12.ulongToTempString(buff) == "12");
assert(long.sizeof.sizeToTempString(buff) == "8");
assert(uint.max.uintToTempString(buff) == "4294967295");
assert(ulong.max.ulongToTempString(buff) == "18446744073709551615");
}


int dstrcmp( in char[] s1, in char[] s2 )
{
int ret = 0;
auto len = s1.length;
if( s2.length < len )
len = s2.length;
if( 0 != (ret = memcmp( s1.ptr, s2.ptr, len )) )
return ret;
return s1.length > s2.length ? 1 :
s1.length == s2.length ? 0 : -1;
}
2 changes: 1 addition & 1 deletion win32.mak
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ copydir: $(IMPDIR)

copy: $(COPY)

$(IMPDIR)\object.di : src\object.di
$(IMPDIR)\object.di : src\object_.d
copy $** $@

$(IMPDIR)\core\atomic.d : src\core\atomic.d
Expand Down
2 changes: 1 addition & 1 deletion win64.mak
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ copydir: $(IMPDIR)

copy: $(COPY)

$(IMPDIR)\object.di : src\object.di
$(IMPDIR)\object.di : src\object_.d
copy $** $@

$(IMPDIR)\core\atomic.d : src\core\atomic.d
Expand Down