aboutsummaryrefslogtreecommitdiff
path: root/libphobos/libdruntime
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2024-01-18 02:39:20 +0100
committerIain Buclaw <ibuclaw@gdcproject.org>2024-02-03 00:49:46 +0100
commitf204359931866b917856fc959c70dbf55f28c14d (patch)
treeba1c671045e384fa49a6381f79abf7c1b84a55ea /libphobos/libdruntime
parent5470a9b176c2b3030ff3891c7e9403db2b0685b8 (diff)
downloadgcc-f204359931866b917856fc959c70dbf55f28c14d.zip
gcc-f204359931866b917856fc959c70dbf55f28c14d.tar.gz
gcc-f204359931866b917856fc959c70dbf55f28c14d.tar.bz2
d: Merge dmd, druntime bce5c1f7b5, phobos e4d0dd513.
D front-end changes: - Import latest changes from dmd v2.107.0-beta.1. - Keywords like `__FILE__' are now always evaluated at the callsite. D runtime changes: - Import latest changes from druntime v2.107.0-beta.1. - Added `nameSig' field to TypeInfo_Class in object.d. Phobos changes: - Import latest changes from phobos v2.107.0-beta.1. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd bce5c1f7b5. * d-attribs.cc (build_attributes): Update for new front-end interface. * d-lang.cc (d_parse_file): Likewise. * decl.cc (DeclVisitor::visit (VarDeclaration *)): Likewise. * expr.cc (build_lambda_tree): New function. (ExprVisitor::visit (FuncExp *)): Use build_lambda_tree. (ExprVisitor::visit (SymOffExp *)): Likewise. (ExprVisitor::visit (VarExp *)): Likewise. * typeinfo.cc (create_tinfo_types): Add two ulong fields to internal TypeInfo representation. (TypeInfoVisitor::visit (TypeInfoClassDeclaration *)): Emit stub data for TypeInfo_Class.nameSig. (TypeInfoVisitor::visit (TypeInfoStructDeclaration *)): Update for new front-end interface. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime bce5c1f7b5. * src/MERGE: Merge upstream phobos e4d0dd513.
Diffstat (limited to 'libphobos/libdruntime')
-rw-r--r--libphobos/libdruntime/MERGE2
-rw-r--r--libphobos/libdruntime/core/exception.d12
-rw-r--r--libphobos/libdruntime/core/internal/container/array.d6
-rw-r--r--libphobos/libdruntime/core/internal/container/common.d4
-rw-r--r--libphobos/libdruntime/core/internal/dassert.d7
-rw-r--r--libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d34
-rw-r--r--libphobos/libdruntime/core/internal/gc/os.d19
-rw-r--r--libphobos/libdruntime/core/internal/spinlock.d4
-rw-r--r--libphobos/libdruntime/core/memory.d11
-rw-r--r--libphobos/libdruntime/core/stdc/assert_.d9
-rw-r--r--libphobos/libdruntime/core/stdc/errno.d234
-rw-r--r--libphobos/libdruntime/core/stdc/fenv.d43
-rw-r--r--libphobos/libdruntime/core/stdc/locale.d17
-rw-r--r--libphobos/libdruntime/core/stdc/stdio.d150
-rw-r--r--libphobos/libdruntime/core/stdc/stdlib.d3
-rw-r--r--libphobos/libdruntime/core/stdc/string.d7
-rw-r--r--libphobos/libdruntime/core/stdc/wchar_.d14
-rw-r--r--libphobos/libdruntime/core/sys/windows/basetsd.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/commctrl.d8
-rw-r--r--libphobos/libdruntime/core/sys/windows/ddeml.d8
-rw-r--r--libphobos/libdruntime/core/sys/windows/dll.d57
-rw-r--r--libphobos/libdruntime/core/sys/windows/httpext.d4
-rw-r--r--libphobos/libdruntime/core/sys/windows/imagehlp.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/msacm.d4
-rw-r--r--libphobos/libdruntime/core/sys/windows/ntsecapi.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/ole.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/prsht.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/rpcdce.d4
-rw-r--r--libphobos/libdruntime/core/sys/windows/rpcdcep.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/rpcnsi.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/setupapi.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/shellapi.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/shlwapi.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/subauth.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/vfw.d2
-rw-r--r--libphobos/libdruntime/core/sys/windows/windef.d68
-rw-r--r--libphobos/libdruntime/core/sys/windows/wininet.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/winsvc.d4
-rw-r--r--libphobos/libdruntime/core/sys/windows/winuser.d4
-rw-r--r--libphobos/libdruntime/core/sys/windows/wtypes.d4
-rw-r--r--libphobos/libdruntime/object.d9
-rw-r--r--libphobos/libdruntime/rt/cast_.d89
-rw-r--r--libphobos/libdruntime/rt/dmain2.d12
43 files changed, 750 insertions, 129 deletions
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE
index 2b4400f..138b0b6 100644
--- a/libphobos/libdruntime/MERGE
+++ b/libphobos/libdruntime/MERGE
@@ -1,4 +1,4 @@
-d8e3976a58d6aef7c2c9371028a2ca4460b5b2ce
+bce5c1f7b521d22dcf1ea4e2bc3f76d9d28274fa
The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository.
diff --git a/libphobos/libdruntime/core/exception.d b/libphobos/libdruntime/core/exception.d
index d2016b1..959ce83 100644
--- a/libphobos/libdruntime/core/exception.d
+++ b/libphobos/libdruntime/core/exception.d
@@ -697,17 +697,17 @@ else
* Throws:
* $(LREF OutOfMemoryError).
*/
- extern (C) noreturn onOutOfMemoryError(void* pretend_sideffect = null) @trusted pure nothrow @nogc /* dmd @@@BUG11461@@@ */
+ extern (C) noreturn onOutOfMemoryError(void* pretend_sideffect = null, string file = __FILE__, size_t line = __LINE__) @trusted pure nothrow @nogc /* dmd @@@BUG11461@@@ */
{
// NOTE: Since an out of memory condition exists, no allocation must occur
// while generating this object.
- throw staticError!OutOfMemoryError();
+ throw staticError!OutOfMemoryError(file, line);
}
- extern (C) noreturn onOutOfMemoryErrorNoGC() @trusted nothrow @nogc
+ extern (C) noreturn onOutOfMemoryErrorNoGC(string file = __FILE__, size_t line = __LINE__) @trusted nothrow @nogc
{
// suppress stacktrace until they are @nogc
- throw staticError!OutOfMemoryError(false);
+ throw staticError!OutOfMemoryError(false, file, line);
}
}
@@ -718,11 +718,11 @@ else
* Throws:
* $(LREF InvalidMemoryOperationError).
*/
-extern (C) noreturn onInvalidMemoryOperationError(void* pretend_sideffect = null) @trusted pure nothrow @nogc /* dmd @@@BUG11461@@@ */
+extern (C) noreturn onInvalidMemoryOperationError(void* pretend_sideffect = null, string file = __FILE__, size_t line = __LINE__) @trusted pure nothrow @nogc /* dmd @@@BUG11461@@@ */
{
// The same restriction applies as for onOutOfMemoryError. The GC is in an
// undefined state, thus no allocation must occur while generating this object.
- throw staticError!InvalidMemoryOperationError();
+ throw staticError!InvalidMemoryOperationError(file, line);
}
diff --git a/libphobos/libdruntime/core/internal/container/array.d b/libphobos/libdruntime/core/internal/container/array.d
index 27292cd..b583341 100644
--- a/libphobos/libdruntime/core/internal/container/array.d
+++ b/libphobos/libdruntime/core/internal/container/array.d
@@ -9,7 +9,7 @@ module core.internal.container.array;
static import common = core.internal.container.common;
-import core.exception : onOutOfMemoryErrorNoGC;
+import core.exception : onOutOfMemoryError;
struct Array(T)
{
@@ -47,7 +47,7 @@ nothrow:
_length = nlength;
}
else
- onOutOfMemoryErrorNoGC();
+ onOutOfMemoryError();
}
@@ -103,7 +103,7 @@ nothrow:
back = val;
}
else
- onOutOfMemoryErrorNoGC();
+ onOutOfMemoryError();
}
void popBack()
diff --git a/libphobos/libdruntime/core/internal/container/common.d b/libphobos/libdruntime/core/internal/container/common.d
index 582d63b..659b2b5 100644
--- a/libphobos/libdruntime/core/internal/container/common.d
+++ b/libphobos/libdruntime/core/internal/container/common.d
@@ -18,7 +18,7 @@ void* xrealloc(void* ptr, size_t sz) nothrow @nogc
if (!sz) { .free(ptr); return null; }
if (auto nptr = .realloc(ptr, sz)) return nptr;
- .free(ptr); onOutOfMemoryErrorNoGC();
+ .free(ptr); onOutOfMemoryError();
assert(0);
}
@@ -27,7 +27,7 @@ void* xmalloc(size_t sz) nothrow @nogc
import core.exception;
if (auto nptr = .malloc(sz))
return nptr;
- onOutOfMemoryErrorNoGC();
+ onOutOfMemoryError();
assert(0);
}
diff --git a/libphobos/libdruntime/core/internal/dassert.d b/libphobos/libdruntime/core/internal/dassert.d
index dbad0e6..76948c8 100644
--- a/libphobos/libdruntime/core/internal/dassert.d
+++ b/libphobos/libdruntime/core/internal/dassert.d
@@ -180,6 +180,8 @@ private string miniFormat(V)(const scope ref V v)
/// `shared` values are formatted as their base type
static if (is(V == shared T, T))
{
+ import core.atomic : atomicLoad;
+
// Use atomics to avoid race conditions whenever possible
static if (__traits(compiles, atomicLoad(v)))
{
@@ -472,11 +474,6 @@ private bool[] calcFieldOverlap(const scope size_t[] offsets)
return overlaps;
}
-// This should be a local import in miniFormat but fails with a cyclic dependency error
-// core.thread.osthread -> core.time -> object -> core.internal.array.capacity
-// -> core.atomic -> core.thread -> core.thread.osthread
-import core.atomic : atomicLoad;
-
/// Negates a comparison token, e.g. `==` is mapped to `!=`
private string invertCompToken(scope string comp) pure nothrow @nogc @safe
{
diff --git a/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d b/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d
index 6f19412..ca4577f 100644
--- a/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d
+++ b/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d
@@ -94,8 +94,8 @@ private
// Declared as an extern instead of importing core.exception
// to avoid inlining - see https://issues.dlang.org/show_bug.cgi?id=13725.
- void onInvalidMemoryOperationError(void* pretend_sideffect = null) @trusted pure nothrow @nogc;
- void onOutOfMemoryErrorNoGC() @trusted nothrow @nogc;
+ void onInvalidMemoryOperationError(void* pretend_sideffect = null, string file = __FILE__, size_t line = __LINE__) @trusted pure nothrow @nogc;
+ void onOutOfMemoryError(void* pretend_sideffect = null, string file = __FILE__, size_t line = __LINE__) @trusted nothrow @nogc;
version (COLLECT_FORK)
version (OSX)
@@ -141,7 +141,7 @@ private GC initialize()
auto gc = cast(ConservativeGC) cstdlib.malloc(__traits(classInstanceSize, ConservativeGC));
if (!gc)
- onOutOfMemoryErrorNoGC();
+ onOutOfMemoryError();
return emplace(gc);
}
@@ -160,7 +160,7 @@ class ConservativeGC : GC
Gcx *gcx; // implementation
- static gcLock = shared(AlignedSpinLock)(SpinLock.Contention.lengthy);
+ static gcLock = shared(AlignedSpinLock)(SpinLock.Contention.brief);
static bool _inFinalizer;
__gshared bool isPrecise = false;
@@ -188,7 +188,7 @@ class ConservativeGC : GC
gcx = cast(Gcx*)cstdlib.calloc(1, Gcx.sizeof);
if (!gcx)
- onOutOfMemoryErrorNoGC();
+ onOutOfMemoryError();
gcx.initialize();
if (config.initReserve)
@@ -509,7 +509,7 @@ class ConservativeGC : GC
auto p = gcx.alloc(size + SENTINEL_EXTRA, alloc_size, bits, ti);
if (!p)
- onOutOfMemoryErrorNoGC();
+ onOutOfMemoryError();
debug (SENTINEL)
{
@@ -1968,7 +1968,7 @@ struct Gcx
// tryAlloc will succeed if a new pool was allocated above, if it fails allocate a new pool now
if (!tryAlloc() && (!newPool(1, false) || !tryAlloc()))
// out of luck or memory
- onOutOfMemoryErrorNoGC();
+ onOutOfMemoryError();
}
assert(p !is null);
L_hasBin:
@@ -2008,7 +2008,7 @@ struct Gcx
size_t pn;
immutable npages = LargeObjectPool.numPages(size);
if (npages == size_t.max)
- onOutOfMemoryErrorNoGC(); // size just below size_t.max requested
+ onOutOfMemoryError(); // size just below size_t.max requested
bool tryAlloc() nothrow
{
@@ -2248,7 +2248,7 @@ struct Gcx
enum initSize = 64 * 1024; // Windows VirtualAlloc granularity
immutable ncap = _cap ? 2 * _cap : initSize / RANGE.sizeof;
auto p = cast(RANGE*)os_mem_map(ncap * RANGE.sizeof);
- if (p is null) onOutOfMemoryErrorNoGC();
+ if (p is null) onOutOfMemoryError();
debug (VALGRIND) makeMemUndefined(p[0..ncap]);
if (_p !is null)
{
@@ -3394,7 +3394,7 @@ Lmark:
scanThreadData = cast(ScanThreadData*) cstdlib.calloc(numScanThreads, ScanThreadData.sizeof);
if (!scanThreadData)
- onOutOfMemoryErrorNoGC();
+ onOutOfMemoryError();
evStart.initialize(false, false);
evDone.initialize(false, false);
@@ -3610,7 +3610,7 @@ struct Pool
{
rtinfo = cast(immutable(size_t)**)cstdlib.malloc(npages * (size_t*).sizeof);
if (!rtinfo)
- onOutOfMemoryErrorNoGC();
+ onOutOfMemoryError();
memset(rtinfo, 0, npages * (size_t*).sizeof);
}
else
@@ -3633,13 +3633,13 @@ struct Pool
pagetable = cast(Bins*)cstdlib.malloc(npages * Bins.sizeof);
if (!pagetable)
- onOutOfMemoryErrorNoGC();
+ onOutOfMemoryError();
if (npages > 0)
{
bPageOffsets = cast(uint*)cstdlib.malloc(npages * uint.sizeof);
if (!bPageOffsets)
- onOutOfMemoryErrorNoGC();
+ onOutOfMemoryError();
if (isLargeObject)
{
@@ -4643,14 +4643,14 @@ debug (LOGGING)
{
data = cast(Log*)cstdlib.malloc(allocdim * Log.sizeof);
if (!data && allocdim)
- onOutOfMemoryErrorNoGC();
+ onOutOfMemoryError();
}
else
{ Log *newdata;
newdata = cast(Log*)cstdlib.malloc(allocdim * Log.sizeof);
if (!newdata && allocdim)
- onOutOfMemoryErrorNoGC();
+ onOutOfMemoryError();
memcpy(newdata, data, dim * Log.sizeof);
cstdlib.free(data);
data = newdata;
@@ -4989,8 +4989,8 @@ version (D_LP64) unittest
// only run if the system has enough physical memory
size_t sz = 2L^^32;
//import core.stdc.stdio;
- //printf("availphys = %lld", os_physical_mem());
- if (os_physical_mem() > sz)
+ //printf("availphys = %lld", os_physical_mem(true));
+ if (os_physical_mem(true) > sz)
{
import core.memory;
GC.collect();
diff --git a/libphobos/libdruntime/core/internal/gc/os.d b/libphobos/libdruntime/core/internal/gc/os.d
index 38b60cb..0db1753 100644
--- a/libphobos/libdruntime/core/internal/gc/os.d
+++ b/libphobos/libdruntime/core/internal/gc/os.d
@@ -254,23 +254,26 @@ bool isLowOnMem(size_t mapped) nothrow @nogc
/**
Get the size of available physical memory
+ Params:
+ avail = if supported on the current platform, return the currently unused memory
+ rather than the installed physical memory
Returns:
size of installed physical RAM
*/
version (Windows)
{
- ulong os_physical_mem() nothrow @nogc
+ ulong os_physical_mem(bool avail) nothrow @nogc
{
import core.sys.windows.winbase : GlobalMemoryStatus, MEMORYSTATUS;
MEMORYSTATUS stat;
GlobalMemoryStatus(&stat);
- return stat.dwTotalPhys; // limited to 4GB for Win32
+ return avail ? stat.dwAvailPhys : stat.dwTotalPhys; // limited to 4GB for Win32
}
}
else version (Darwin)
{
extern (C) int sysctl(const int* name, uint namelen, void* oldp, size_t* oldlenp, const void* newp, size_t newlen) @nogc nothrow;
- ulong os_physical_mem() nothrow @nogc
+ ulong os_physical_mem(bool avail) nothrow @nogc
{
enum
{
@@ -287,11 +290,15 @@ else version (Darwin)
}
else version (Posix)
{
- ulong os_physical_mem() nothrow @nogc
+ ulong os_physical_mem(bool avail) nothrow @nogc
{
- import core.sys.posix.unistd : sysconf, _SC_PAGESIZE, _SC_PHYS_PAGES;
+ import core.sys.posix.unistd;
const pageSize = sysconf(_SC_PAGESIZE);
- const pages = sysconf(_SC_PHYS_PAGES);
+ static if (__traits(compiles, _SC_AVPHYS_PAGES)) // not available on all platforms
+ const sc = avail ? _SC_AVPHYS_PAGES : _SC_PHYS_PAGES;
+ else
+ const sc = _SC_PHYS_PAGES;
+ const pages = sysconf(sc);
return pageSize * pages;
}
}
diff --git a/libphobos/libdruntime/core/internal/spinlock.d b/libphobos/libdruntime/core/internal/spinlock.d
index 36d806a..b0ea8f6 100644
--- a/libphobos/libdruntime/core/internal/spinlock.d
+++ b/libphobos/libdruntime/core/internal/spinlock.d
@@ -53,9 +53,9 @@ shared struct SpinLock
import core.time;
if (k < pauseThresh)
return core.atomic.pause();
- else if (k < 32)
+ else // if (k < 32)
return Thread.yield();
- Thread.sleep(1.msecs);
+ // Thread.sleep(1.msecs);
}
private:
diff --git a/libphobos/libdruntime/core/memory.d b/libphobos/libdruntime/core/memory.d
index 4f44b60..f2a48f9 100644
--- a/libphobos/libdruntime/core/memory.d
+++ b/libphobos/libdruntime/core/memory.d
@@ -266,8 +266,8 @@ extern(C):
/**
* Enables automatic garbage collection behavior if collections have
- * previously been suspended by a call to disable. This function is
- * reentrant, and must be called once for every call to disable before
+ * previously been suspended by a call to `GC.disable()`. This function is
+ * reentrant, and must be called once for every call to `GC.disable()` before
* automatic collections are enabled.
*/
pragma(mangle, "gc_enable") static void enable() @safe nothrow pure;
@@ -278,7 +278,12 @@ extern(C):
* process footprint. Collections may continue to occur in instances
* where the implementation deems necessary for correct program behavior,
* such as during an out of memory condition. This function is reentrant,
- * but enable must be called once for each call to disable.
+ * but `GC.enable()` must be called once for each call to `GC.disable()`.
+ * Unlike the
+ * $(LINK2 https://dlang.org/spec/function.html#nogc-functions, `@nogc` attribute),
+ * `GC.disable()` halts
+ * collections across all threads, yet still allows GC allocations.
+ * Disabling collections eliminates GC pauses.
*/
pragma(mangle, "gc_disable") static void disable() @safe nothrow pure;
diff --git a/libphobos/libdruntime/core/stdc/assert_.d b/libphobos/libdruntime/core/stdc/assert_.d
index d6cb8a6..c6d9d9f 100644
--- a/libphobos/libdruntime/core/stdc/assert_.d
+++ b/libphobos/libdruntime/core/stdc/assert_.d
@@ -113,6 +113,15 @@ else version (CRuntime_Musl)
*/
noreturn __assert_fail(const(char)* exp, const(char)* file, uint line, const(char)* func);
}
+else version (CRuntime_Newlib)
+{
+ /***
+ * Assert failure function in the Newlib library.
+ */
+ noreturn __assert(const(char)* file, int line, const(char)* exp);
+ ///
+ noreturn __assert_func(const(char)* file, int line, const(char)* func, const(char)* exp);
+}
else version (CRuntime_UClibc)
{
noreturn __assert(const(char)* exp, const(char)* file, uint line, const(char)* func);
diff --git a/libphobos/libdruntime/core/stdc/errno.d b/libphobos/libdruntime/core/stdc/errno.d
index e503dd9..ddec70f 100644
--- a/libphobos/libdruntime/core/stdc/errno.d
+++ b/libphobos/libdruntime/core/stdc/errno.d
@@ -75,6 +75,14 @@ else version (CRuntime_Musl)
alias errno = __errno_location;
}
}
+else version (CRuntime_Newlib)
+{
+ extern (C)
+ {
+ ref int __errno();
+ alias errno = __errno;
+ }
+}
else version (OpenBSD)
{
// https://github.com/openbsd/src/blob/master/include/errno.h
@@ -164,7 +172,7 @@ else
extern (C):
-version (Windows)
+version (CRuntime_DigitalMars)
{
enum EPERM = 1; /// Operation not permitted
enum ENOENT = 2; /// No such file or directory
@@ -250,6 +258,230 @@ version (Windows)
enum ETXTBSY = 139;
enum EWOULDBLOCK = 140;
}
+else version (CRuntime_Microsoft)
+{
+ enum EPERM = 1; /// Operation not permitted
+ enum ENOENT = 2; /// No such file or directory
+ enum ESRCH = 3; /// No such process
+ enum EINTR = 4; /// Interrupted system call
+ enum EIO = 5; /// I/O error
+ enum ENXIO = 6; /// No such device or address
+ enum E2BIG = 7; /// Argument list too long
+ enum ENOEXEC = 8; /// Exec format error
+ enum EBADF = 9; /// Bad file number
+ enum ECHILD = 10; /// No child processes
+ enum EAGAIN = 11; /// Try again
+ enum ENOMEM = 12; /// Out of memory
+ enum EACCES = 13; /// Permission denied
+ enum EFAULT = 14; /// Bad address
+ enum EBUSY = 16; /// Device or resource busy
+ enum EEXIST = 17; /// File exists
+ enum EXDEV = 18; /// Cross-device link
+ enum ENODEV = 19; /// No such device
+ enum ENOTDIR = 20; /// Not a directory
+ enum EISDIR = 21; /// Is a directory
+ enum EINVAL = 22; /// Invalid argument
+ enum ENFILE = 23; /// File table overflow
+ enum EMFILE = 24; /// Too many open files
+ enum ENOTTY = 25; /// Not a typewriter
+ enum EFBIG = 27; /// File too large
+ enum ENOSPC = 28; /// No space left on device
+ enum ESPIPE = 29; /// Illegal seek
+ enum EROFS = 30; /// Read-only file system
+ enum EMLINK = 31; /// Too many links
+ enum EPIPE = 32; /// Broken pipe
+ enum EDOM = 33; /// Math argument out of domain of func
+ enum ERANGE = 34; /// Math result not representable
+ enum EDEADLK = 36; /// Resource deadlock would occur
+ enum ENAMETOOLONG = 38; /// File name too long
+ enum ENOLCK = 39; /// No record locks available
+ enum ENOSYS = 40; /// Function not implemented
+ enum ENOTEMPTY = 41; /// Directory not empty
+ enum EILSEQ = 42; /// Illegal byte sequence
+ enum EDEADLOCK = EDEADLK; /// Resource deadlock would occur
+
+ // POSIX compatibility
+ // See_Also: https://docs.microsoft.com/en-us/cpp/c-runtime-library/errno-constants
+ enum EADDRINUSE = 100;
+ enum EADDRNOTAVAIL = 101;
+ enum EAFNOSUPPORT = 102;
+ enum EALREADY = 103;
+ enum EBADMSG = 104;
+ enum ECANCELED = 105;
+ enum ECONNABORTED = 106;
+ enum ECONNREFUSED = 107;
+ enum ECONNRESET = 108;
+ enum EDESTADDRREQ = 109;
+ enum EHOSTUNREACH = 110;
+ enum EIDRM = 111;
+ enum EINPROGRESS = 112;
+ enum EISCONN = 113;
+ enum ELOOP = 114;
+ enum EMSGSIZE = 115;
+ enum ENETDOWN = 116;
+ enum ENETRESET = 117;
+ enum ENETUNREACH = 118;
+ enum ENOBUFS = 119;
+ enum ENODATA = 120;
+ enum ENOLINK = 121;
+ enum ENOMSG = 122;
+ enum ENOPROTOOPT = 123;
+ enum ENOSR = 124;
+ enum ENOSTR = 125;
+ enum ENOTCONN = 126;
+ enum ENOTRECOVERABLE = 127;
+ enum ENOTSOCK = 128;
+ enum ENOTSUP = 129;
+ enum EOPNOTSUPP = 130;
+ enum EOTHER = 131;
+ enum EOVERFLOW = 132;
+ enum EOWNERDEAD = 133;
+ enum EPROTO = 134;
+ enum EPROTONOSUPPORT = 135;
+ enum EPROTOTYPE = 136;
+ enum ETIME = 137;
+ enum ETIMEDOUT = 138;
+ enum ETXTBSY = 139;
+ enum EWOULDBLOCK = 140;
+}
+else version (CRuntime_Newlib)
+{
+ enum EPERM = 1;
+ enum ENOENT = 2;
+ enum ESRCH = 3;
+ enum EINTR = 4;
+ enum EIO = 5;
+ enum ENXIO = 6;
+ enum E2BIG = 7;
+ enum ENOEXEC = 8;
+ enum EBADF = 9;
+ enum ECHILD = 10;
+ enum EAGAIN = 11;
+ enum ENOMEM = 12;
+ enum EACCES = 13;
+ enum EFAULT = 14;
+ enum EBUSY = 16;
+ enum EEXIST = 17;
+ enum EXDEV = 18;
+ enum ENODEV = 19;
+ enum ENOTDIR = 20;
+ enum EISDIR = 21;
+ enum EINVAL = 22;
+ enum ENFILE = 23;
+ enum EMFILE = 24;
+ enum ENOTTY = 25;
+ enum ETXTBSY = 26;
+ enum EFBIG = 27;
+ enum ENOSPC = 28;
+ enum ESPIPE = 29;
+ enum EROFS = 30;
+ enum EMLINK = 31;
+ enum EPIPE = 32;
+ enum EDOM = 33;
+ enum ERANGE = 34;
+ enum ENOMSG = 35;
+ enum EIDRM = 36;
+ enum EDEADLK = 45;
+ enum ENOLCK = 46;
+ enum ENOSTR = 60;
+ enum ENODATA = 61;
+ enum ETIME = 62;
+ enum ENOSR = 63;
+ enum ENOLINK = 67;
+ enum EPROTO = 71;
+ enum EMULTIHOP = 74;
+ enum EBADMSG = 77;
+ enum EFTYPE = 79;
+ enum ENOSYS = 88;
+ enum ENOTEMPTY = 90;
+ enum ENAMETOOLONG = 91;
+ enum ELOOP = 92;
+ enum EOPNOTSUPP = 95;
+ enum EPFNOSUPPORT = 96;
+ enum ECONNRESET = 104;
+ enum ENOBUFS = 105;
+ enum EAFNOSUPPORT = 106;
+ enum EPROTOTYPE = 107;
+ enum ENOTSOCK = 108;
+ enum ENOPROTOOPT = 109;
+ enum ECONNREFUSED = 111;
+ enum EADDRINUSE = 112;
+ enum ECONNABORTED = 113;
+ enum ENETUNREACH = 114;
+ enum ENETDOWN = 115;
+ enum ETIMEDOUT = 116;
+ enum EHOSTDOWN = 117;
+ enum EHOSTUNREACH = 118;
+ enum EINPROGRESS = 119;
+ enum EALREADY = 120;
+ enum EDESTADDRREQ = 121;
+ enum EMSGSIZE = 122;
+ enum EPROTONOSUPPORT = 123;
+ enum EADDRNOTAVAIL = 125;
+ enum ENETRESET = 126;
+ enum EISCONN = 127;
+ enum ENOTCONN = 128;
+ enum ETOOMANYREFS = 129;
+ enum EDQUOT = 132;
+ enum ESTALE = 133;
+ enum ENOTSUP = 134;
+ enum EILSEQ = 138;
+ enum EOVERFLOW = 139;
+ enum ECANCELED = 140;
+ enum ENOTRECOVERABLE = 141;
+ enum EOWNERDEAD = 142;
+
+ enum EWOULDBLOCK = EAGAIN;
+
+ enum __ELASTERROR = 2000;
+
+ // Linux errno extensions
+ version (Cygwin)
+ {
+ enum ENOTBLK = 15;
+ enum ECHRNG = 37;
+ enum EL2NSYNC = 38;
+ enum EL3HLT = 39;
+ enum EL3RST = 40;
+ enum ELNRNG = 41;
+ enum EUNATCH = 42;
+ enum ENOCSI = 43;
+ enum EL2HLT = 44;
+ enum EBADE = 50;
+ enum EBADR = 51;
+ enum EXFULL = 52;
+ enum ENOANO = 53;
+ enum EBADRQC = 54;
+ enum EBADSLT = 55;
+ enum EDEADLOCK = 56;
+ enum EBFONT = 57;
+ enum ENONET = 64;
+ enum ENOPKG = 65;
+ enum EREMOTE = 66;
+ enum EADV = 68;
+ enum ESRMNT = 69;
+ enum ECOMM = 70;
+ enum ELBIN = 75;
+ enum EDOTDOT = 76;
+ enum ENOTUNIQ = 80;
+ enum EBADFD = 81;
+ enum EREMCHG = 82;
+ enum ELIBACC = 83;
+ enum ELIBBAD = 84;
+ enum ELIBSCN = 85;
+ enum ELIBMAX = 86;
+ enum ELIBEXEC = 87;
+ enum ENMFILE = 89;
+ enum ESHUTDOWN = 110;
+ enum ESOCKTNOSUPPORT = 124;
+ enum EPROCLIM = 130;
+ enum EUSERS = 131;
+ enum ENOMEDIUM = 135;
+ enum ENOSHARE = 136;
+ enum ECASECLASH = 137;
+ enum ESTRPIPE = 143;
+ }
+}
else version (linux)
{
enum EPERM = 1; ///
diff --git a/libphobos/libdruntime/core/stdc/fenv.d b/libphobos/libdruntime/core/stdc/fenv.d
index 0051ecd..a7364c0 100644
--- a/libphobos/libdruntime/core/stdc/fenv.d
+++ b/libphobos/libdruntime/core/stdc/fenv.d
@@ -448,6 +448,49 @@ else version (CRuntime_Musl)
static assert(false, "Architecture not supported.");
}
}
+else version (CRuntime_Newlib)
+{
+ version (AArch64)
+ {
+ alias fenv_t = ulong;
+ alias fexcept_t = ulong;
+ }
+ else version (RISCV_Any)
+ {
+ alias fenv_t = size_t;
+ alias fexcept_t = size_t;
+ }
+ else version (X86_Any)
+ {
+ struct fenv_t
+ {
+ uint _fpu_cw;
+ uint _fpu_sw;
+ uint _fpu_tagw;
+ uint _fpu_ipoff;
+ uint _fpu_ipsel;
+ uint _fpu_opoff;
+ uint _fpu_opsel;
+ uint _sse_mxcsr;
+ }
+ alias fexcept_t = uint;
+ }
+ else version (SPARC64)
+ {
+ alias fenv_t = ulong;
+ alias fexcept_t = ulong;
+ }
+ else version (SPARC)
+ {
+ alias fenv_t = uint;
+ alias fexcept_t = uint;
+ }
+ else
+ {
+ alias fenv_t = int;
+ alias fexcept_t = int;
+ }
+}
else version (CRuntime_UClibc)
{
version (X86)
diff --git a/libphobos/libdruntime/core/stdc/locale.d b/libphobos/libdruntime/core/stdc/locale.d
index 4b8d5c8..357d75e 100644
--- a/libphobos/libdruntime/core/stdc/locale.d
+++ b/libphobos/libdruntime/core/stdc/locale.d
@@ -252,6 +252,23 @@ else version (CRuntime_Musl)
///
enum LC_ALL = 6;
}
+else version (CRuntime_Newlib)
+{
+ ///
+ enum LC_ALL = 0;
+ ///
+ enum LC_COLLATE = 1;
+ ///
+ enum LC_CTYPE = 2;
+ ///
+ enum LC_MONETARY = 3;
+ ///
+ enum LC_NUMERIC = 4;
+ ///
+ enum LC_TIME = 5;
+ ///
+ enum LC_MESSAGES = 6;
+}
else version (CRuntime_UClibc)
{
///
diff --git a/libphobos/libdruntime/core/stdc/stdio.d b/libphobos/libdruntime/core/stdc/stdio.d
index ee37da1..1fc0461 100644
--- a/libphobos/libdruntime/core/stdc/stdio.d
+++ b/libphobos/libdruntime/core/stdc/stdio.d
@@ -328,6 +328,30 @@ else version (CRuntime_Bionic)
int _size;
}
}
+else version (CRuntime_Newlib)
+{
+ enum
+ {
+ ///
+ BUFSIZ = 1024,
+ ///
+ EOF = -1,
+ ///
+ FOPEN_MAX = 20,
+ ///
+ FILENAME_MAX = 1024,
+ ///
+ TMP_MAX = 26,
+ ///
+ L_tmpnam = 1024
+ }
+
+ struct __sbuf
+ {
+ ubyte* _base;
+ int _size;
+ }
+}
else version (CRuntime_UClibc)
{
enum
@@ -769,6 +793,57 @@ else version (CRuntime_Bionic)
///
alias shared(__sFILE) FILE;
}
+else version (CRuntime_Newlib)
+{
+ import core.sys.posix.sys.types : ssize_t;
+ import core.stdc.wchar_ : mbstate_t;
+
+ ///
+ alias fpos_t = c_long;
+
+ ///
+ struct __sFILE
+ {
+ ubyte* _p;
+ int _r;
+ int _w;
+ short _flags;
+ short _file;
+ __sbuf _bf;
+ int _lbfsize;
+
+ void* _data;
+ void* _cookie;
+
+ ssize_t function(void*, void*, scope char*, size_t) _read;
+ ssize_t function(void*, void*, scope const char*, size_t) _write;
+ fpos_t function(void*, void*, fpos_t, int) _seek;
+ int function(void*, void*) _close;
+
+ __sbuf _ub;
+ ubyte* _up;
+ int _ur;
+
+ ubyte[3] _ubuf;
+ ubyte[1] _nbuf;
+
+ __sbuf _lb;
+
+ int _blksize;
+ int _flags2;
+
+ long _offset;
+ void* _unused;
+
+ void* _lock;
+ mbstate_t _mbstate;
+ }
+
+ ///
+ alias __sFILE _iobuf; // needed for phobos
+ ///
+ alias shared(__sFILE) FILE;
+}
else version (CRuntime_UClibc)
{
import core.stdc.wchar_ : mbstate_t;
@@ -1137,6 +1212,40 @@ else version (CRuntime_Musl)
_IONBF = 2,
}
}
+else version (CRuntime_Newlib)
+{
+ enum
+ {
+ ///
+ _IOFBF = 0,
+ ///
+ _IOLBF = 1,
+ ///
+ _IONBF = 2,
+ }
+
+ private
+ {
+ shared struct _reent
+ {
+ int _errno;
+ __sFILE* _stdin;
+ __sFILE* _stdout;
+ __sFILE* _stderr;
+ }
+ _reent* __getreent();
+ }
+
+ pragma(inline, true)
+ {
+ ///
+ @property auto stdin()() { return __getreent()._stdin; }
+ ///
+ @property auto stdout()() { return __getreent()._stdout; }
+ ///
+ @property auto stderr()() { return __getreent()._stderr; }
+ }
+}
else version (CRuntime_UClibc)
{
enum
@@ -1869,6 +1978,47 @@ else version (CRuntime_Musl)
pragma(printf)
int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
}
+else version (CRuntime_Newlib)
+{
+ // No unsafe pointer manipulation.
+ @trusted
+ {
+ ///
+ void rewind(FILE* stream);
+ ///
+ pure void clearerr(FILE* stream);
+ ///
+ pure int feof(FILE* stream);
+ ///
+ pure int ferror(FILE* stream);
+ ///
+ int fileno(FILE *);
+ }
+
+ ///
+ pragma(printf)
+ int snprintf(scope char* s, size_t n, scope const char* format, scope const ...);
+ ///
+ pragma(printf)
+ int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
+
+ //
+ // Gnu under-the-hood C I/O functions. Uses _iobuf* for the unshared
+ // version of FILE*, usable when the FILE is locked.
+ // See http://gnu.org/software/libc/manual/html_node/I_002fO-on-Streams.html
+ //
+ import core.stdc.wchar_ : wint_t;
+ import core.stdc.stddef : wchar_t;
+
+ ///
+ int fputc_unlocked(int c, _iobuf* stream);
+ ///
+ int fgetc_unlocked(_iobuf* stream);
+ ///
+ wint_t fputwc_unlocked(wchar_t wc, _iobuf* stream);
+ ///
+ wint_t fgetwc_unlocked(_iobuf* stream);
+}
else version (CRuntime_UClibc)
{
// No unsafe pointer manipulation.
diff --git a/libphobos/libdruntime/core/stdc/stdlib.d b/libphobos/libdruntime/core/stdc/stdlib.d
index 0b42de8..bd5fc2b 100644
--- a/libphobos/libdruntime/core/stdc/stdlib.d
+++ b/libphobos/libdruntime/core/stdc/stdlib.d
@@ -28,6 +28,8 @@ else version (WatchOS)
version (CRuntime_Glibc)
version = AlignedAllocSupported;
+else version (CRuntime_Newlib)
+ version = AlignedAllocSupported;
else {}
extern (C):
@@ -97,6 +99,7 @@ else version (DragonFlyBSD) enum RAND_MAX = 0x7fffffff;
else version (Solaris) enum RAND_MAX = 0x7fff;
else version (CRuntime_Bionic) enum RAND_MAX = 0x7fffffff;
else version (CRuntime_Musl) enum RAND_MAX = 0x7fffffff;
+else version (CRuntime_Newlib) enum RAND_MAX = 0x7fffffff;
else version (CRuntime_UClibc) enum RAND_MAX = 0x7fffffff;
else version (WASI) enum RAND_MAX = 0x7fffffff;
else static assert( false, "Unsupported platform" );
diff --git a/libphobos/libdruntime/core/stdc/string.d b/libphobos/libdruntime/core/stdc/string.d
index 3591a6d..b9e3bb7 100644
--- a/libphobos/libdruntime/core/stdc/string.d
+++ b/libphobos/libdruntime/core/stdc/string.d
@@ -72,8 +72,15 @@ version (ReturnStrerrorR)
const(char)* strerror_r(int errnum, return scope char* buf, size_t buflen);
}
// This one is
+else version (CRuntime_Newlib)
+{
+ ///
+ pragma(mangle, "__xpg_strerror_r")
+ int strerror_r(int errnum, scope char* buf, size_t buflen);
+}
else
{
+ ///
int strerror_r(int errnum, scope char* buf, size_t buflen);
}
///
diff --git a/libphobos/libdruntime/core/stdc/wchar_.d b/libphobos/libdruntime/core/stdc/wchar_.d
index 2d01e26..6ed2dfe 100644
--- a/libphobos/libdruntime/core/stdc/wchar_.d
+++ b/libphobos/libdruntime/core/stdc/wchar_.d
@@ -106,6 +106,20 @@ else version (Solaris)
///
alias mbstate_t = __mbstate_t;
}
+else version (CRuntime_Newlib)
+{
+ ///
+ struct mbstate_t
+ {
+ int __count;
+ union ___value
+ {
+ wint_t __wch = 0;
+ char[4] __wchb;
+ }
+ ___value __value;
+ }
+}
else version (CRuntime_UClibc)
{
///
diff --git a/libphobos/libdruntime/core/sys/windows/basetsd.d b/libphobos/libdruntime/core/sys/windows/basetsd.d
index e70dbdc..1e5a454 100644
--- a/libphobos/libdruntime/core/sys/windows/basetsd.d
+++ b/libphobos/libdruntime/core/sys/windows/basetsd.d
@@ -15,9 +15,6 @@ version (Windows):
// import.
alias HANDLE = void*;
-package template DECLARE_HANDLE(string name, base = HANDLE) {
- mixin ("alias " ~ base.stringof ~ " " ~ name ~ ";");
-}
alias HANDLE* PHANDLE, LPHANDLE;
// helper for aligned structs
diff --git a/libphobos/libdruntime/core/sys/windows/commctrl.d b/libphobos/libdruntime/core/sys/windows/commctrl.d
index dabee56..fe4ebbc 100644
--- a/libphobos/libdruntime/core/sys/windows/commctrl.d
+++ b/libphobos/libdruntime/core/sys/windows/commctrl.d
@@ -1740,8 +1740,8 @@ enum {
I_CHILDRENCALLBACK = -1
}
-mixin DECLARE_HANDLE!("HTREEITEM");
-mixin DECLARE_HANDLE!("HIMAGELIST");
+alias HTREEITEM = HANDLE;
+alias HIMAGELIST = HANDLE;
version (Win64)
{
@@ -4482,8 +4482,8 @@ static if (_WIN32_IE >= 0x400) {
alias RBHITTESTINFO* LPRBHITTESTINFO;
}
-mixin DECLARE_HANDLE!("HDSA");
-mixin DECLARE_HANDLE!("HDPA");
+alias HDSA = HANDLE;
+alias HDPA = HANDLE;
version (Unicode) {
alias HDITEMW HDITEM;
diff --git a/libphobos/libdruntime/core/sys/windows/ddeml.d b/libphobos/libdruntime/core/sys/windows/ddeml.d
index 00bad1d..2e8e3ee 100644
--- a/libphobos/libdruntime/core/sys/windows/ddeml.d
+++ b/libphobos/libdruntime/core/sys/windows/ddeml.d
@@ -15,10 +15,10 @@ pragma(lib, "user32");
import core.sys.windows.basetsd, core.sys.windows.windef, core.sys.windows.winnt;
-mixin DECLARE_HANDLE!("HCONVLIST");
-mixin DECLARE_HANDLE!("HCONV");
-mixin DECLARE_HANDLE!("HSZ");
-mixin DECLARE_HANDLE!("HDDEDATA");
+alias HCONVLIST = HANDLE;
+alias HCONV = HANDLE;
+alias HSZ = HANDLE;
+alias HDDEDATA = HANDLE;
enum : int {
CP_WINANSI = 1004,
diff --git a/libphobos/libdruntime/core/sys/windows/dll.d b/libphobos/libdruntime/core/sys/windows/dll.d
index 5b02fb5..77141d5 100644
--- a/libphobos/libdruntime/core/sys/windows/dll.d
+++ b/libphobos/libdruntime/core/sys/windows/dll.d
@@ -487,10 +487,20 @@ bool dll_process_attach( HINSTANCE hInstance, bool attach_threads,
}, null );
}
-/** same as above, but only usable if druntime is linked statically
+version (Shared) version (DigitalMars) private extern(C) extern __gshared void* __ImageBase;
+
+/** same as above, but checking for shared runtime
*/
+pragma(inline, false) // version (Shared) only set when compiling druntime
bool dll_process_attach( HINSTANCE hInstance, bool attach_threads = true )
{
+ version (Shared) version (DigitalMars)
+ {
+ // cannot declare rt_initSharedModule globally as it then conflicts with the definition in sections_win64.d
+ pragma(mangle, "rt_initSharedModule") extern(C) bool rt_initSharedModule( void* handle );
+ if ( hInstance != &__ImageBase )
+ return rt_initSharedModule( hInstance );
+ }
version (Win64)
{
return dll_process_attach( hInstance, attach_threads,
@@ -506,8 +516,16 @@ bool dll_process_attach( HINSTANCE hInstance, bool attach_threads = true )
/**
* to be called from DllMain with reason DLL_PROCESS_DETACH
*/
+pragma(inline, false) // version (Shared) only set when compiling druntime
void dll_process_detach( HINSTANCE hInstance, bool detach_threads = true )
{
+ version (Shared) version (DigitalMars)
+ {
+ // cannot declare rt_termSharedModule globally as it then conflicts with the definition in sections_win64.d
+ pragma(mangle, "rt_termSharedModule") extern(C) bool rt_termSharedModule( void* handle );
+ if ( hInstance != &__ImageBase )
+ return cast(void) rt_termSharedModule( hInstance );
+ }
// notify core.thread.joinLowLevelThread that the DLL is about to be unloaded
thread_DLLProcessDetaching = true;
@@ -531,6 +549,21 @@ void dll_process_detach( HINSTANCE hInstance, bool detach_threads = true )
Runtime.terminate();
}
+/*****************************
+* Check whether the D runtime is built as a DLL or linked statically
+*
+* Returns:
+* true = DLL, false = static library
+*/
+pragma(inline, false) // version (Shared) only set when compiling druntime
+bool isSharedDRuntime()
+{
+ version (Shared)
+ return true;
+ else
+ return false;
+}
+
/* Make sure that tlsCtorRun is itself a tls variable
*/
static bool tlsCtorRun;
@@ -542,8 +575,15 @@ static ~this() { tlsCtorRun = false; }
* Returns:
* true for success, false for failure
*/
-bool dll_thread_attach( bool attach_thread = true, bool initTls = true )
+pragma(inline, false) // version (Shared) only set when compiling druntime
+bool dll_thread_attach( bool attach_thread = true, bool initTls = true, HINSTANCE hInstance = null )
{
+ version (Shared) version (DigitalMars)
+ {
+ if ( hInstance && hInstance != &__ImageBase )
+ return true;
+ }
+
// if the OS has not prepared TLS for us, don't attach to the thread
// (happened when running under x64 OS)
auto tid = GetCurrentThreadId();
@@ -565,8 +605,15 @@ bool dll_thread_attach( bool attach_thread = true, bool initTls = true )
* Returns:
* true for success, false for failure
*/
-bool dll_thread_detach( bool detach_thread = true, bool exitTls = true )
+pragma(inline, false) // version (Shared) only set when compiling druntime
+bool dll_thread_detach( bool detach_thread = true, bool exitTls = true, HINSTANCE hInstance = null )
{
+ version (Shared) version (DigitalMars)
+ {
+ if ( hInstance && hInstance != &__ImageBase )
+ return true;
+ }
+
// if the OS has not prepared TLS for us, we did not attach to the thread
if ( !GetTlsDataAddress( GetCurrentThreadId() ) )
return false;
@@ -613,10 +660,10 @@ mixin template SimpleDllMain()
return true;
case DLL_THREAD_ATTACH:
- return dll_thread_attach( true, true );
+ return dll_thread_attach( true, true, hInstance );
case DLL_THREAD_DETACH:
- return dll_thread_detach( true, true );
+ return dll_thread_detach( true, true, hInstance );
}
}
}
diff --git a/libphobos/libdruntime/core/sys/windows/httpext.d b/libphobos/libdruntime/core/sys/windows/httpext.d
index 6973879..200b284 100644
--- a/libphobos/libdruntime/core/sys/windows/httpext.d
+++ b/libphobos/libdruntime/core/sys/windows/httpext.d
@@ -19,7 +19,7 @@ version (Windows):
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
-import core.sys.windows.basetsd /+: DECLARE_HANDLE, HANDLE+/;
+import core.sys.windows.basetsd /+: HANDLE+/;
import core.sys.windows.windef /+: BOOL, CHAR, DWORD, LPBYTE, LPDWORD+/;
import core.sys.windows.winnt /+: LPCSTR, LPSTR, LPVOID, PVOID, VOID+/;
@@ -47,7 +47,7 @@ enum {
HSE_IO_SEND_HEADERS = 0x00000008
}
-mixin DECLARE_HANDLE!("HCONN");
+alias HCONN = HANDLE;
struct HSE_VERSION_INFO {
DWORD dwExtensionVersion;
diff --git a/libphobos/libdruntime/core/sys/windows/imagehlp.d b/libphobos/libdruntime/core/sys/windows/imagehlp.d
index 399c0b2..68d88d7 100644
--- a/libphobos/libdruntime/core/sys/windows/imagehlp.d
+++ b/libphobos/libdruntime/core/sys/windows/imagehlp.d
@@ -275,7 +275,7 @@ struct IMAGEHLP_DUPLICATE_SYMBOL {
}
alias IMAGEHLP_DUPLICATE_SYMBOL* PIMAGEHLP_DUPLICATE_SYMBOL;
-mixin DECLARE_HANDLE!("DIGEST_HANDLE");
+alias DIGEST_HANDLE = HANDLE;
extern (Windows) {
alias BOOL function(IMAGEHLP_STATUS_REASON, LPSTR, LPSTR, ULONG_PTR, ULONG_PTR)
diff --git a/libphobos/libdruntime/core/sys/windows/msacm.d b/libphobos/libdruntime/core/sys/windows/msacm.d
index 645e40d..df4d6c4 100644
--- a/libphobos/libdruntime/core/sys/windows/msacm.d
+++ b/libphobos/libdruntime/core/sys/windows/msacm.d
@@ -14,8 +14,8 @@ version (ANSI) {} else version = Unicode;
import core.sys.windows.basetsd, core.sys.windows.mmsystem, core.sys.windows.windef;
-mixin DECLARE_HANDLE!("HACMDRIVERID");
-mixin DECLARE_HANDLE!("HACMDRIVER");
+alias HACMDRIVERID = HANDLE;
+alias HACMDRIVER = HANDLE;
alias HACMDRIVER* LPHACMDRIVER;
enum size_t
diff --git a/libphobos/libdruntime/core/sys/windows/ntsecapi.d b/libphobos/libdruntime/core/sys/windows/ntsecapi.d
index fbc6b7f..fa08a74 100644
--- a/libphobos/libdruntime/core/sys/windows/ntsecapi.d
+++ b/libphobos/libdruntime/core/sys/windows/ntsecapi.d
@@ -666,7 +666,7 @@ struct POLICY_DOMAIN_KERBEROS_TICKET_INFO {
}
alias POLICY_DOMAIN_KERBEROS_TICKET_INFO* PPOLICY_DOMAIN_KERBEROS_TICKET_INFO;
-mixin DECLARE_HANDLE!("LSA_HANDLE");
+alias LSA_HANDLE = HANDLE;
alias LSA_HANDLE* PLSA_HANDLE;
struct TRUSTED_DOMAIN_NAME_INFO {
diff --git a/libphobos/libdruntime/core/sys/windows/ole.d b/libphobos/libdruntime/core/sys/windows/ole.d
index a844124..b9e55a3 100644
--- a/libphobos/libdruntime/core/sys/windows/ole.d
+++ b/libphobos/libdruntime/core/sys/windows/ole.d
@@ -155,7 +155,7 @@ enum OLEOPT_UPDATE {
// #endif
}
-mixin DECLARE_HANDLE!("HOBJECT");
+alias HOBJECT = HANDLE;
alias LONG_PTR LHSERVER, LHCLIENTDOC, LHSERVERDOC;
struct OLEOBJECTVTBL {
diff --git a/libphobos/libdruntime/core/sys/windows/prsht.d b/libphobos/libdruntime/core/sys/windows/prsht.d
index 92596b5..053b1fa 100644
--- a/libphobos/libdruntime/core/sys/windows/prsht.d
+++ b/libphobos/libdruntime/core/sys/windows/prsht.d
@@ -247,7 +247,7 @@ struct PROPSHEETPAGEW {
alias PROPSHEETPAGEW* LPPROPSHEETPAGEW;
alias const(PROPSHEETPAGEW)* LPCPROPSHEETPAGEW;
-mixin DECLARE_HANDLE!("HPROPSHEETPAGE");
+alias HPROPSHEETPAGE = HANDLE;
struct PROPSHEETHEADERA {
DWORD dwSize = PROPSHEETHEADERA.sizeof;
diff --git a/libphobos/libdruntime/core/sys/windows/rpcdce.d b/libphobos/libdruntime/core/sys/windows/rpcdce.d
index 4f3f3cc..951480b 100644
--- a/libphobos/libdruntime/core/sys/windows/rpcdce.d
+++ b/libphobos/libdruntime/core/sys/windows/rpcdce.d
@@ -160,8 +160,8 @@ struct RPC_IF_ID_VECTOR {
uint Count;
RPC_IF_ID*[1] IfId;
}
-mixin DECLARE_HANDLE!("RPC_AUTH_IDENTITY_HANDLE");
-mixin DECLARE_HANDLE!("RPC_AUTHZ_HANDLE");
+alias RPC_AUTH_IDENTITY_HANDLE = HANDLE;
+alias RPC_AUTHZ_HANDLE = HANDLE;
struct RPC_SECURITY_QOS {
uint Version;
diff --git a/libphobos/libdruntime/core/sys/windows/rpcdcep.d b/libphobos/libdruntime/core/sys/windows/rpcdcep.d
index 71b82be..421c275 100644
--- a/libphobos/libdruntime/core/sys/windows/rpcdcep.d
+++ b/libphobos/libdruntime/core/sys/windows/rpcdcep.d
@@ -15,7 +15,7 @@ import core.sys.windows.basetyps;
import core.sys.windows.w32api;
import core.sys.windows.windef;
-mixin DECLARE_HANDLE!("I_RPC_HANDLE");
+alias I_RPC_HANDLE = HANDLE;
alias long RPC_STATUS;
enum RPC_NCA_FLAGS_DEFAULT=0;
diff --git a/libphobos/libdruntime/core/sys/windows/rpcnsi.d b/libphobos/libdruntime/core/sys/windows/rpcnsi.d
index 1294d0d..60c7b09 100644
--- a/libphobos/libdruntime/core/sys/windows/rpcnsi.d
+++ b/libphobos/libdruntime/core/sys/windows/rpcnsi.d
@@ -18,7 +18,7 @@ import core.sys.windows.basetyps, core.sys.windows.rpcdcep, core.sys.windows.rpc
core.sys.windows.w32api;
import core.sys.windows.windef; // for HANDLE
-mixin DECLARE_HANDLE!("RPC_NS_HANDLE");
+alias RPC_NS_HANDLE = HANDLE;
enum RPC_C_NS_SYNTAX_DEFAULT=0;
enum RPC_C_NS_SYNTAX_DCE=3;
diff --git a/libphobos/libdruntime/core/sys/windows/setupapi.d b/libphobos/libdruntime/core/sys/windows/setupapi.d
index 7a052cd..da50386 100644
--- a/libphobos/libdruntime/core/sys/windows/setupapi.d
+++ b/libphobos/libdruntime/core/sys/windows/setupapi.d
@@ -858,7 +858,7 @@ enum : DWORD {
alias PVOID HINF;
alias PVOID HDSKSPC;
-mixin DECLARE_HANDLE!("HDEVINFO");
+alias HDEVINFO = HANDLE;
alias PVOID HSPFILEQ;
alias PVOID HSPFILELOG;
diff --git a/libphobos/libdruntime/core/sys/windows/shellapi.d b/libphobos/libdruntime/core/sys/windows/shellapi.d
index fdd9938..2ddf680 100644
--- a/libphobos/libdruntime/core/sys/windows/shellapi.d
+++ b/libphobos/libdruntime/core/sys/windows/shellapi.d
@@ -188,7 +188,7 @@ enum SHERB_NOPROGRESSUI = 2;
enum SHERB_NOSOUND = 4;
alias WORD FILEOP_FLAGS, PRINTEROP_FLAGS;
-mixin DECLARE_HANDLE!("HDROP");
+alias HDROP = HANDLE;
//align(2): // 1 in Win32, default in Win64
diff --git a/libphobos/libdruntime/core/sys/windows/shlwapi.d b/libphobos/libdruntime/core/sys/windows/shlwapi.d
index cfabbad..3562003 100644
--- a/libphobos/libdruntime/core/sys/windows/shlwapi.d
+++ b/libphobos/libdruntime/core/sys/windows/shlwapi.d
@@ -120,7 +120,7 @@ enum URLIS
URLIS_HASQUERY
}
-mixin DECLARE_HANDLE!("HUSKEY");
+alias HUSKEY = HANDLE;
alias HUSKEY* PHUSKEY;
extern (Windows)
diff --git a/libphobos/libdruntime/core/sys/windows/subauth.d b/libphobos/libdruntime/core/sys/windows/subauth.d
index a48fb99..8240d9f4 100644
--- a/libphobos/libdruntime/core/sys/windows/subauth.d
+++ b/libphobos/libdruntime/core/sys/windows/subauth.d
@@ -106,7 +106,7 @@ struct STRING {
alias STRING* PSTRING;
+/
-mixin DECLARE_HANDLE!("SAM_HANDLE");
+alias SAM_HANDLE = HANDLE;
alias SAM_HANDLE* PSAM_HANDLE;
struct OLD_LARGE_INTEGER {
diff --git a/libphobos/libdruntime/core/sys/windows/vfw.d b/libphobos/libdruntime/core/sys/windows/vfw.d
index e8ca74e..c0f22a9 100644
--- a/libphobos/libdruntime/core/sys/windows/vfw.d
+++ b/libphobos/libdruntime/core/sys/windows/vfw.d
@@ -678,7 +678,7 @@ extern (Windows) {
void ICCompressorFree(PCOMPVARS pc);
}
-mixin DECLARE_HANDLE!("HDRAWDIB");
+alias HDRAWDIB = HANDLE;
enum {
DDF_0001 = 0x0001,
diff --git a/libphobos/libdruntime/core/sys/windows/windef.d b/libphobos/libdruntime/core/sys/windows/windef.d
index 4e951f3..105be44 100644
--- a/libphobos/libdruntime/core/sys/windows/windef.d
+++ b/libphobos/libdruntime/core/sys/windows/windef.d
@@ -74,43 +74,43 @@ alias const(void)* PCVOID, LPCVOID;
alias UINT_PTR WPARAM;
alias LONG_PTR LPARAM, LRESULT;
-mixin DECLARE_HANDLE!("HHOOK");
-mixin DECLARE_HANDLE!("HGLOBAL");
-mixin DECLARE_HANDLE!("HLOCAL");
-mixin DECLARE_HANDLE!("GLOBALHANDLE");
-mixin DECLARE_HANDLE!("LOCALHANDLE");
-mixin DECLARE_HANDLE!("HGDIOBJ");
-mixin DECLARE_HANDLE!("HACCEL");
-mixin DECLARE_HANDLE!("HBITMAP", HGDIOBJ);
-mixin DECLARE_HANDLE!("HBRUSH", HGDIOBJ);
-mixin DECLARE_HANDLE!("HCOLORSPACE");
-mixin DECLARE_HANDLE!("HDC");
-mixin DECLARE_HANDLE!("HGLRC");
-mixin DECLARE_HANDLE!("HDESK");
-mixin DECLARE_HANDLE!("HENHMETAFILE");
-mixin DECLARE_HANDLE!("HFONT", HGDIOBJ);
-mixin DECLARE_HANDLE!("HICON");
-mixin DECLARE_HANDLE!("HINSTANCE");
-mixin DECLARE_HANDLE!("HKEY");
-mixin DECLARE_HANDLE!("HMENU");
-mixin DECLARE_HANDLE!("HMETAFILE");
-mixin DECLARE_HANDLE!("HMODULE");
-mixin DECLARE_HANDLE!("HMONITOR");
-mixin DECLARE_HANDLE!("HPALETTE");
-mixin DECLARE_HANDLE!("HPEN", HGDIOBJ);
-mixin DECLARE_HANDLE!("HRGN", HGDIOBJ);
-mixin DECLARE_HANDLE!("HRSRC");
-mixin DECLARE_HANDLE!("HSTR");
-mixin DECLARE_HANDLE!("HTASK");
-mixin DECLARE_HANDLE!("HWND");
-mixin DECLARE_HANDLE!("HWINSTA");
-mixin DECLARE_HANDLE!("HKL");
-mixin DECLARE_HANDLE!("HCURSOR");
+alias HHOOK = HANDLE;
+alias HGLOBAL = HANDLE;
+alias HLOCAL = HANDLE;
+alias GLOBALHANDLE = HANDLE;
+alias LOCALHANDLE = HANDLE;
+alias HGDIOBJ = HANDLE;
+alias HACCEL = HANDLE;
+alias HBITMAP = HGDIOBJ;
+alias HBRUSH = HGDIOBJ;
+alias HCOLORSPACE = HANDLE;
+alias HDC = HANDLE;
+alias HGLRC = HANDLE;
+alias HDESK = HANDLE;
+alias HENHMETAFILE = HANDLE;
+alias HFONT = HGDIOBJ;
+alias HICON = HANDLE;
+alias HINSTANCE = HANDLE;
+alias HKEY = HANDLE;
+alias HMENU = HANDLE;
+alias HMETAFILE = HANDLE;
+alias HMODULE = HANDLE;
+alias HMONITOR = HANDLE;
+alias HPALETTE = HANDLE;
+alias HPEN = HGDIOBJ;
+alias HRGN = HGDIOBJ;
+alias HRSRC = HANDLE;
+alias HSTR = HANDLE;
+alias HTASK = HANDLE;
+alias HWND = HANDLE;
+alias HWINSTA = HANDLE;
+alias HKL = HANDLE;
+alias HCURSOR = HANDLE;
alias HKEY* PHKEY;
static if (_WIN32_WINNT >= 0x500) {
- mixin DECLARE_HANDLE!("HTERMINAL");
- mixin DECLARE_HANDLE!("HWINEVENTHOOK");
+ alias HTERMINAL = HANDLE;
+ alias HWINEVENTHOOK = HANDLE;
}
alias extern (Windows) INT_PTR function() nothrow FARPROC, NEARPROC, PROC;
diff --git a/libphobos/libdruntime/core/sys/windows/wininet.d b/libphobos/libdruntime/core/sys/windows/wininet.d
index 328af50..790d4d0 100644
--- a/libphobos/libdruntime/core/sys/windows/wininet.d
+++ b/libphobos/libdruntime/core/sys/windows/wininet.d
@@ -740,7 +740,8 @@ enum {
INTERNET_CACHE_GROUP_REMOVE = 1
}
-mixin DECLARE_HANDLE!("HINTERNET"); // doesn't work - bug
+alias HINTERNET = HANDLE;
+// mixin DECLARE_HANDLE!("HINTERNET"); // doesn't work - bug
/*struct HINTERNET {
HANDLE h;
alias h this;
diff --git a/libphobos/libdruntime/core/sys/windows/winsvc.d b/libphobos/libdruntime/core/sys/windows/winsvc.d
index f7f2fa7..e6418ac 100644
--- a/libphobos/libdruntime/core/sys/windows/winsvc.d
+++ b/libphobos/libdruntime/core/sys/windows/winsvc.d
@@ -184,10 +184,10 @@ struct SERVICE_TABLE_ENTRYW {
}
alias SERVICE_TABLE_ENTRYW* LPSERVICE_TABLE_ENTRYW;
-mixin DECLARE_HANDLE!("SC_HANDLE");
+alias SC_HANDLE = HANDLE;
alias SC_HANDLE* LPSC_HANDLE;
alias void* SC_LOCK;
-mixin DECLARE_HANDLE!("SERVICE_STATUS_HANDLE");
+alias SERVICE_STATUS_HANDLE = HANDLE;
extern (Windows) {
alias void function(DWORD) LPHANDLER_FUNCTION;
diff --git a/libphobos/libdruntime/core/sys/windows/winuser.d b/libphobos/libdruntime/core/sys/windows/winuser.d
index 829952d..469e68e 100644
--- a/libphobos/libdruntime/core/sys/windows/winuser.d
+++ b/libphobos/libdruntime/core/sys/windows/winuser.d
@@ -2495,8 +2495,8 @@ extern (Windows) nothrow {
alias NAMEENUMPROCW WINSTAENUMPROCW;
}
-mixin DECLARE_HANDLE!("HDWP");
-mixin DECLARE_HANDLE!("HDEVNOTIFY");
+alias HDWP = HANDLE;
+alias HDEVNOTIFY = HANDLE;
struct MENUGETOBJECTINFO {
DWORD dwFlags;
diff --git a/libphobos/libdruntime/core/sys/windows/wtypes.d b/libphobos/libdruntime/core/sys/windows/wtypes.d
index 0206839..881f05a 100644
--- a/libphobos/libdruntime/core/sys/windows/wtypes.d
+++ b/libphobos/libdruntime/core/sys/windows/wtypes.d
@@ -96,8 +96,8 @@ alias OLECHAR* BSTR;
alias FLAGGED_WORD_BLOB* wireBSTR;
alias BSTR* LPBSTR;
//alias LONG SCODE; // also in winerror
-mixin DECLARE_HANDLE!("HCONTEXT");
-mixin DECLARE_HANDLE!("HMETAFILEPICT");
+alias HCONTEXT = HANDLE;
+alias HMETAFILEPICT = HANDLE;
union CY {
struct {
diff --git a/libphobos/libdruntime/object.d b/libphobos/libdruntime/object.d
index 1b39a27..710f4cc 100644
--- a/libphobos/libdruntime/object.d
+++ b/libphobos/libdruntime/object.d
@@ -1646,10 +1646,10 @@ class TypeInfo_Class : TypeInfo
string name; /// class name
void*[] vtbl; /// virtual function pointer table
Interface[] interfaces; /// interfaces this class implements
- TypeInfo_Class base; /// base class
+ TypeInfo_Class base; /// base class
void* destructor;
void function(Object) classInvariant;
- enum ClassFlags : uint
+ enum ClassFlags : ushort
{
isCOMclass = 0x1,
noPointers = 0x2,
@@ -1660,11 +1660,14 @@ class TypeInfo_Class : TypeInfo
isAbstract = 0x40,
isCPPclass = 0x80,
hasDtor = 0x100,
+ hasNameSig = 0x200,
}
ClassFlags m_flags;
- void* deallocator;
+ ushort depth; /// inheritance distance from Object
+ void* deallocator;
OffsetTypeInfo[] m_offTi;
void function(Object) defaultConstructor; // default Constructor
+ ulong[2] nameSig; /// unique signature for `name`
immutable(void)* m_RTInfo; // data for precise GC
override @property immutable(void)* rtInfo() const { return m_RTInfo; }
diff --git a/libphobos/libdruntime/rt/cast_.d b/libphobos/libdruntime/rt/cast_.d
index 925599e..44e0f7a 100644
--- a/libphobos/libdruntime/rt/cast_.d
+++ b/libphobos/libdruntime/rt/cast_.d
@@ -23,10 +23,12 @@ pure:
// but we are trying to implement dynamic cast.
extern (D) private bool areClassInfosEqual(scope const ClassInfo a, scope const ClassInfo b) @safe
{
- if (a is b)
- return true;
- // take care of potential duplicates across binaries
- return a.name == b.name;
+ // same class if signatures match, works with potential duplicates across binaries
+ return a is b ||
+ (a.m_flags & TypeInfo_Class.ClassFlags.hasNameSig
+ ? (a.nameSig[0] == b.nameSig[0] &&
+ a.nameSig[1] == b.nameSig[1]) // new fast way
+ : (a is b || a.name == b.name)); // old slow way for temporary binary compatibility
}
/******************************************
@@ -58,7 +60,7 @@ Object _d_toObject(return scope void* p)
}
/*************************************
- * Attempts to cast Object o to class c.
+ * Attempts to cast interface Object o to class c.
* Returns o if successful, null if not.
*/
void* _d_interface_cast(void* p, ClassInfo c)
@@ -70,9 +72,26 @@ void* _d_interface_cast(void* p, ClassInfo c)
Interface* pi = **cast(Interface***) p;
debug(cast_) printf("\tpi.offset = %d\n", pi.offset);
- return _d_dynamic_cast(cast(Object)(p - pi.offset), c);
+ Object o2 = cast(Object)(p - pi.offset);
+ void* res = null;
+ size_t offset = 0;
+ if (o2 && _d_isbaseof2(typeid(o2), c, offset))
+ {
+ debug(cast_) printf("\toffset = %d\n", offset);
+ res = cast(void*) o2 + offset;
+ }
+ debug(cast_) printf("\tresult = %p\n", res);
+ return res;
}
+/*****
+ * Dynamic cast from a class object `o` to class or interface `c`, where `c` is a subtype of `o`.
+ * Params:
+ * o = instance of class
+ * c = a subclass of o
+ * Returns:
+ * null if o is null or c is not a subclass of o. Otherwise, return o.
+ */
void* _d_dynamic_cast(Object o, ClassInfo c)
{
debug(cast_) printf("_d_dynamic_cast(o = %p, c = '%.*s')\n", o, c.name);
@@ -88,6 +107,64 @@ void* _d_dynamic_cast(Object o, ClassInfo c)
return res;
}
+/*****
+ * Dynamic cast from a class object o to class c, where c is a subclass of o.
+ * Params:
+ * o = instance of class
+ * c = a subclass of o
+ * Returns:
+ * null if o is null or c is not a subclass of o. Otherwise, return o.
+ */
+void* _d_class_cast(Object o, ClassInfo c)
+{
+ debug(cast_) printf("_d_cast_cast(o = %p, c = '%.*s', level %d)\n", o, c.name, level);
+
+ if (!o)
+ return null;
+
+ ClassInfo oc = typeid(o);
+ int delta = oc.depth;
+
+ if (delta && c.depth)
+ {
+ delta -= c.depth;
+ if (delta < 0)
+ return null;
+
+ while (delta--)
+ oc = oc.base;
+ if (areClassInfosEqual(oc, c))
+ return cast(void*)o;
+ return null;
+ }
+
+ // no depth data - support the old way
+ do
+ {
+ if (areClassInfosEqual(oc, c))
+ return cast(void*)o;
+ oc = oc.base;
+ } while (oc);
+ return null;
+}
+
+/**
+ * Dynamic cast `o` to final class `c` only one level down
+ * Params:
+ * o = object that is instance of a class
+ * c = class to cast it to
+ * Returns:
+ * o if it succeeds, null if it fails
+ */
+void* _d_paint_cast(Object o, ClassInfo c)
+{
+ /* If o is really an instance of c, just do a paint
+ */
+ auto p = (o && cast(void*)(areClassInfosEqual(typeid(o), c)) ? o : null);
+ debug assert(cast(void*)p is cast(void*)_d_dynamic_cast(o, c));
+ return cast(void*)p;
+}
+
int _d_isbaseof2(scope ClassInfo oc, scope const ClassInfo c, scope ref size_t offset) @safe
{
if (areClassInfosEqual(oc, c))
diff --git a/libphobos/libdruntime/rt/dmain2.d b/libphobos/libdruntime/rt/dmain2.d
index 8a10aac..5ac053c 100644
--- a/libphobos/libdruntime/rt/dmain2.d
+++ b/libphobos/libdruntime/rt/dmain2.d
@@ -496,6 +496,13 @@ private extern (C) int _d_run_main2(char[][] args, size_t totalArgsLength, MainF
{
if (rt_init())
{
+ version(Shared) version(CRuntime_Microsoft) version (DigitalMars)
+ {
+ auto exeHandle = handleForAddr(mainFunc);
+ if (exeHandle)
+ if (!rt_initSharedModule(exeHandle))
+ exeHandle = null;
+ }
auto utResult = runModuleUnitTests();
assert(utResult.passed <= utResult.executed);
if (utResult.passed == utResult.executed)
@@ -521,6 +528,11 @@ private extern (C) int _d_run_main2(char[][] args, size_t totalArgsLength, MainF
cast(int)utResult.executed);
result = EXIT_FAILURE;
}
+ version(Shared) version(CRuntime_Microsoft) version (DigitalMars)
+ {
+ if (exeHandle)
+ rt_termSharedModule(exeHandle);
+ }
}
else
result = EXIT_FAILURE;