aboutsummaryrefslogtreecommitdiff
path: root/libphobos
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
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')
-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
-rw-r--r--libphobos/src/MERGE2
-rw-r--r--libphobos/src/std/bitmanip.d4
-rw-r--r--libphobos/src/std/complex.d2
-rw-r--r--libphobos/src/std/conv.d8
-rw-r--r--libphobos/src/std/exception.d6
-rw-r--r--libphobos/src/std/format/internal/floats.d14
-rw-r--r--libphobos/src/std/format/internal/write.d7
-rw-r--r--libphobos/src/std/math/algebraic.d2
-rw-r--r--libphobos/src/std/math/exponential.d44
-rw-r--r--libphobos/src/std/math/hardware.d8
-rw-r--r--libphobos/src/std/math/operations.d21
-rw-r--r--libphobos/src/std/math/package.d166
-rw-r--r--libphobos/src/std/math/rounding.d4
-rw-r--r--libphobos/src/std/math/traits.d179
-rw-r--r--libphobos/src/std/math/trigonometry.d5
-rw-r--r--libphobos/src/std/mmfile.d68
-rw-r--r--libphobos/src/std/regex/internal/backtracking.d2
-rw-r--r--libphobos/src/std/regex/internal/ir.d4
-rw-r--r--libphobos/src/std/typecons.d56
62 files changed, 1073 insertions, 408 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 4f44b604..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;
diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE
index 103a93f..b29da3b 100644
--- a/libphobos/src/MERGE
+++ b/libphobos/src/MERGE
@@ -1,4 +1,4 @@
-7a6e9568862f5a0d9eb34707d85dcf7ff889c26f
+e4d0dd5136be3c539a02cc2f1618cb989a685837
The first line of this file holds the git revision number of the last
merge done from the dlang/phobos repository.
diff --git a/libphobos/src/std/bitmanip.d b/libphobos/src/std/bitmanip.d
index b84a676..e9f6191 100644
--- a/libphobos/src/std/bitmanip.d
+++ b/libphobos/src/std/bitmanip.d
@@ -279,10 +279,8 @@ See_Also: $(REF BitFlags, std,typecons)
*/
string bitfields(T...)()
{
- import std.conv : to;
-
static assert(T.length % 3 == 0,
- "Wrong number of arguments (" ~ to!string(T.length) ~ "): Must be a multiple of 3");
+ "Wrong number of arguments (" ~ T.length.stringof ~ "): Must be a multiple of 3");
static foreach (i, ARG; T)
{
diff --git a/libphobos/src/std/complex.d b/libphobos/src/std/complex.d
index 347e351..60746f9 100644
--- a/libphobos/src/std/complex.d
+++ b/libphobos/src/std/complex.d
@@ -1892,7 +1892,7 @@ Complex!T pow(T)(const T x, Complex!T n) @trusted pure nothrow @nogc
@safe pure nothrow @nogc unittest
{
import std.meta : AliasSeq;
- import std.math : RealFormat, floatTraits;
+ import std.math.traits : floatTraits, RealFormat;
static foreach (T; AliasSeq!(float, double, real))
{{
static if (floatTraits!T.realFormat == RealFormat.ibmExtended)
diff --git a/libphobos/src/std/conv.d b/libphobos/src/std/conv.d
index 23b33c4..5d02df0 100644
--- a/libphobos/src/std/conv.d
+++ b/libphobos/src/std/conv.d
@@ -1804,7 +1804,7 @@ if (!is(S : T) && isAssociativeArray!S &&
}
static void testFloatingToIntegral(Floating, Integral)()
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
bool convFails(Source, Target, E)(Source src)
{
@@ -3430,7 +3430,7 @@ if (isFloatingPoint!Target && !is(Target == enum) &&
Target result = cast(Target) (sign ? -ldval : ldval);
// if overflow occurred
- import std.math : isFinite;
+ import std.math.traits : isFinite;
enforce(isFinite(result), new ConvException("Range error"));
advanceSource();
@@ -3598,7 +3598,7 @@ if (isFloatingPoint!Target && !is(Target == enum) &&
@system unittest
{
// @system because strtod is not @safe.
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
static if (floatTraits!real.realFormat == RealFormat.ieeeDouble)
{
@@ -3682,7 +3682,7 @@ if (isFloatingPoint!Target && !is(Target == enum) &&
{
import core.stdc.errno;
import core.stdc.stdlib;
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
errno = 0; // In case it was set by another unittest in a different module.
struct longdouble
diff --git a/libphobos/src/std/exception.d b/libphobos/src/std/exception.d
index 5c78685..58a667c 100644
--- a/libphobos/src/std/exception.d
+++ b/libphobos/src/std/exception.d
@@ -1632,6 +1632,9 @@ class ErrnoException : Exception
/// Operating system error code.
final @property uint errno() nothrow pure scope @nogc @safe { return _errno; }
private uint _errno;
+ /// Localized error message generated through $(REF strerror_r, core,stdc,string) or $(REF strerror, core,stdc,string).
+ final @property string errnoMsg() nothrow pure scope @nogc @safe { return _errnoMsg; }
+ private string _errnoMsg;
/// Constructor which takes an error message. The current global $(REF errno, core,stdc,errno) value is used as error code.
this(string msg, string file = null, size_t line = 0) @safe
{
@@ -1642,7 +1645,8 @@ class ErrnoException : Exception
this(string msg, int errno, string file = null, size_t line = 0) @safe
{
_errno = errno;
- super(msg ~ " (" ~ errnoString(errno) ~ ")", file, line);
+ _errnoMsg = errnoString(errno);
+ super(msg ~ " (" ~ errnoMsg ~ ")", file, line);
}
}
diff --git a/libphobos/src/std/format/internal/floats.d b/libphobos/src/std/format/internal/floats.d
index afe0bfa..88b9d22 100644
--- a/libphobos/src/std/format/internal/floats.d
+++ b/libphobos/src/std/format/internal/floats.d
@@ -28,6 +28,15 @@ if (is(T == float) || is(T == double)
return w.data;
}
+/// Returns: whether `c` is a supported format specifier for floats
+package(std.format) bool isFloatSpec(char c) nothrow @nogc pure @safe
+{
+ return c == 'a' || c == 'A'
+ || c == 'e' || c == 'E'
+ || c == 'f' || c == 'F'
+ || c == 'g' || c == 'G';
+}
+
package(std.format) void printFloat(Writer, T, Char)(auto ref Writer w, const(T) val, FormatSpec!Char f)
if (is(T == float) || is(T == double)
|| (is(T == real) && (T.mant_dig == double.mant_dig || T.mant_dig == 64)))
@@ -43,10 +52,7 @@ if (is(T == float) || is(T == double)
if (sgn == "" && f.flPlus) sgn = "+";
if (sgn == "" && f.flSpace) sgn = " ";
- assert(f.spec == 'a' || f.spec == 'A'
- || f.spec == 'e' || f.spec == 'E'
- || f.spec == 'f' || f.spec == 'F'
- || f.spec == 'g' || f.spec == 'G', "unsupported format specifier");
+ assert(isFloatSpec(f.spec), "unsupported format specifier");
bool is_upper = f.spec == 'A' || f.spec == 'E' || f.spec=='F' || f.spec=='G';
// special treatment for nan and inf
diff --git a/libphobos/src/std/format/internal/write.d b/libphobos/src/std/format/internal/write.d
index 85954fa..16c7a51 100644
--- a/libphobos/src/std/format/internal/write.d
+++ b/libphobos/src/std/format/internal/write.d
@@ -570,9 +570,9 @@ void formatValueImpl(Writer, T, Char)(auto ref Writer w, const(T) obj,
scope const ref FormatSpec!Char f)
if (is(FloatingPointTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))
{
- import std.algorithm.searching : find;
import std.format : enforceFmt;
import std.range.primitives : put;
+ import std.format.internal.floats : printFloat, isFloatSpec;
FloatingPointTypeOf!T val = obj;
const char spec = f.spec;
@@ -597,11 +597,9 @@ if (is(FloatingPointTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))
return;
}
- enforceFmt(find("fgFGaAeEs", spec).length,
- "incompatible format character for floating point argument: %" ~ spec);
-
FormatSpec!Char fs = f; // fs is copy for change its values.
fs.spec = spec == 's' ? 'g' : spec;
+ enforceFmt(isFloatSpec(fs.spec), "incompatible format character for floating point argument: %" ~ spec);
static if (is(T == float) || is(T == double)
|| (is(T == real) && (T.mant_dig == double.mant_dig || T.mant_dig == 64)))
@@ -631,7 +629,6 @@ if (is(FloatingPointTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))
tval = -doubleLowest;
}
- import std.format.internal.floats : printFloat;
printFloat(w, tval, fs);
}
diff --git a/libphobos/src/std/math/algebraic.d b/libphobos/src/std/math/algebraic.d
index 9999071..fd30523 100644
--- a/libphobos/src/std/math/algebraic.d
+++ b/libphobos/src/std/math/algebraic.d
@@ -308,7 +308,7 @@ if (isFloatingPoint!T)
// If both are huge, avoid overflow by scaling by 2^^-N.
// If both are tiny, avoid underflow by scaling by 2^^N.
import core.math : fabs, sqrt;
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
alias F = floatTraits!T;
diff --git a/libphobos/src/std/math/exponential.d b/libphobos/src/std/math/exponential.d
index 8290479..5e90f0d 100644
--- a/libphobos/src/std/math/exponential.d
+++ b/libphobos/src/std/math/exponential.d
@@ -1002,8 +1002,7 @@ float exp(float x) @safe pure nothrow @nogc { return __ctfe ? cast(float) exp(ca
private T expImpl(T)(T x) @safe pure nothrow @nogc
{
- import std.math : floatTraits, RealFormat;
- import std.math.traits : isNaN;
+ import std.math.traits : floatTraits, RealFormat, isNaN;
import std.math.rounding : floor;
import std.math.algebraic : poly;
import std.math.constants : LOG2E;
@@ -1143,7 +1142,7 @@ private T expImpl(T)(T x) @safe pure nothrow @nogc
@safe @nogc nothrow unittest
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
import std.math.operations : NaN, feqrel, isClose;
import std.math.constants : E;
import std.math.traits : isIdentical;
@@ -1517,7 +1516,7 @@ L_largenegative:
private T expm1Impl(T)(T x) @safe pure nothrow @nogc
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
import std.math.rounding : floor;
import std.math.algebraic : poly;
import std.math.constants : LN2;
@@ -1909,8 +1908,7 @@ L_was_nan:
private T exp2Impl(T)(T x) @nogc @safe pure nothrow
{
- import std.math : floatTraits, RealFormat;
- import std.math.traits : isNaN;
+ import std.math.traits : floatTraits, RealFormat, isNaN;
import std.math.rounding : floor;
import std.math.algebraic : poly;
@@ -2098,8 +2096,7 @@ private T exp2Impl(T)(T x) @nogc @safe pure nothrow
T frexp(T)(const T value, out int exp) @trusted pure nothrow @nogc
if (isFloatingPoint!T)
{
- import std.math : floatTraits, RealFormat, MANTISSA_MSB, MANTISSA_LSB;
- import std.math.traits : isSubnormal;
+ import std.math.traits : floatTraits, RealFormat, MANTISSA_MSB, MANTISSA_LSB, isSubnormal;
if (__ctfe)
{
@@ -2353,8 +2350,7 @@ if (isFloatingPoint!T)
@safe unittest
{
- import std.math : floatTraits, RealFormat;
- import std.math.traits : isIdentical;
+ import std.math.traits : floatTraits, RealFormat, isIdentical;
import std.meta : AliasSeq;
import std.typecons : tuple, Tuple;
@@ -2486,7 +2482,7 @@ if (isFloatingPoint!T)
int ilogb(T)(const T x) @trusted pure nothrow @nogc
if (isFloatingPoint!T)
{
- import std.math : floatTraits, RealFormat, MANTISSA_MSB, MANTISSA_LSB;
+ import std.math.traits : floatTraits, RealFormat, MANTISSA_MSB, MANTISSA_LSB;
import core.bitop : bsr;
alias F = floatTraits!T;
@@ -2681,7 +2677,7 @@ alias FP_ILOGBNAN = core.stdc.math.FP_ILOGBNAN;
@safe nothrow @nogc unittest
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
import std.math.operations : nextUp;
import std.meta : AliasSeq;
import std.typecons : Tuple;
@@ -2778,7 +2774,7 @@ float ldexp(float n, int exp) @safe pure nothrow @nogc { return core.math.ldex
@safe pure nothrow @nogc unittest
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
static if (floatTraits!(real).realFormat == RealFormat.ieeeExtended ||
floatTraits!(real).realFormat == RealFormat.ieeeExtended53 ||
@@ -2866,7 +2862,7 @@ private
// Coefficients shared across log(), log2(), log10(), log1p().
template LogCoeffs(T)
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
static if (floatTraits!T.realFormat == RealFormat.ieeeQuadruple)
{
@@ -3179,8 +3175,7 @@ private T logImpl(T, bool LOG1P = false)(T x) @safe pure nothrow @nogc
{
import std.math.constants : SQRT1_2;
import std.math.algebraic : poly;
- import std.math.traits : isInfinity, isNaN, signbit;
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : isInfinity, isNaN, signbit, floatTraits, RealFormat;
alias coeffs = LogCoeffs!T;
alias F = floatTraits!T;
@@ -3306,7 +3301,7 @@ private T logImpl(T, bool LOG1P = false)(T x) @safe pure nothrow @nogc
@safe @nogc nothrow unittest
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
import std.meta : AliasSeq;
static void testLog(T)(T[2][] vals)
@@ -3452,8 +3447,7 @@ private T log10Impl(T)(T x) @safe pure nothrow @nogc
{
import std.math.constants : SQRT1_2;
import std.math.algebraic : poly;
- import std.math.traits : isNaN, isInfinity, signbit;
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : isNaN, isInfinity, signbit, floatTraits, RealFormat;
alias coeffs = LogCoeffs!T;
alias F = floatTraits!T;
@@ -3558,7 +3552,7 @@ Ldone:
@safe @nogc nothrow unittest
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
import std.meta : AliasSeq;
static void testLog10(T)(T[2][] vals)
@@ -3710,7 +3704,7 @@ private T log1pImpl(T)(T x) @safe pure nothrow @nogc
import std.math.traits : isNaN, isInfinity, signbit;
import std.math.algebraic : poly;
import std.math.constants : SQRT1_2, SQRT2;
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
// Special cases.
if (isNaN(x) || x == 0.0)
@@ -3746,7 +3740,7 @@ private T log1pImpl(T)(T x) @safe pure nothrow @nogc
@safe @nogc nothrow unittest
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
import std.meta : AliasSeq;
static void testLog1p(T)(T[2][] vals)
@@ -3891,7 +3885,7 @@ private T log2Impl(T)(T x) @safe pure nothrow @nogc
import std.math.traits : isNaN, isInfinity, signbit;
import std.math.constants : SQRT1_2, LOG2E;
import std.math.algebraic : poly;
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
alias coeffs = LogCoeffs!T;
alias F = floatTraits!T;
@@ -3972,7 +3966,7 @@ Ldone:
@safe @nogc nothrow unittest
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
import std.meta : AliasSeq;
static void testLog2(T)(T[2][] vals)
@@ -4172,7 +4166,7 @@ private T logbImpl(T)(T x) @trusted pure nothrow @nogc
@safe @nogc nothrow unittest
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
import std.meta : AliasSeq;
static void testLogb(T)(T[2][] vals)
diff --git a/libphobos/src/std/math/hardware.d b/libphobos/src/std/math/hardware.d
index cb6cb87..c7c5d6e 100644
--- a/libphobos/src/std/math/hardware.d
+++ b/libphobos/src/std/math/hardware.d
@@ -210,14 +210,12 @@ private:
}
else version (RISCV_Any)
{
- mixin(`
uint result = void;
asm pure nothrow @nogc
{
"frflags %0" : "=r" (result);
}
return result;
- `);
}
else version (LoongArch_Any)
{
@@ -307,13 +305,11 @@ private:
}
else version (RISCV_Any)
{
- mixin(`
uint newValues = 0x0;
asm pure nothrow @nogc
{
"fsflags %0" : : "r" (newValues);
}
- `);
}
else version (LoongArch_Any)
{
@@ -1039,14 +1035,12 @@ private:
}
else version (RISCV_Any)
{
- mixin(`
ControlState cont;
asm pure nothrow @nogc
{
"frcsr %0" : "=r" (cont);
}
return cont;
- `);
}
else version (LoongArch_Any)
{
@@ -1163,12 +1157,10 @@ private:
}
else version (RISCV_Any)
{
- mixin(`
asm pure nothrow @nogc
{
"fscsr %0" : : "r" (newState);
}
- `);
}
else version (LoongArch_Any)
{
diff --git a/libphobos/src/std/math/operations.d b/libphobos/src/std/math/operations.d
index 4bf19ee..d456e29 100644
--- a/libphobos/src/std/math/operations.d
+++ b/libphobos/src/std/math/operations.d
@@ -44,7 +44,7 @@ import std.traits : CommonType, isFloatingPoint, isIntegral, Unqual;
*/
real NaN(ulong payload) @trusted pure nothrow @nogc
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
alias F = floatTraits!(real);
static if (F.realFormat == RealFormat.ieeeExtended ||
@@ -136,7 +136,7 @@ real NaN(ulong payload) @trusted pure nothrow @nogc
@system pure nothrow @nogc unittest // not @safe because taking address of local.
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
static if (floatTraits!(real).realFormat == RealFormat.ieeeDouble)
{
@@ -159,7 +159,7 @@ real NaN(ulong payload) @trusted pure nothrow @nogc
*/
ulong getNaNPayload(real x) @trusted pure nothrow @nogc
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
// assert(isNaN(x));
alias F = floatTraits!(real);
@@ -283,7 +283,7 @@ debug(UnitTest)
*/
real nextUp(real x) @trusted pure nothrow @nogc
{
- import std.math : floatTraits, RealFormat, MANTISSA_MSB, MANTISSA_LSB;
+ import std.math.traits : floatTraits, RealFormat, MANTISSA_MSB, MANTISSA_LSB;
alias F = floatTraits!(real);
static if (F.realFormat != RealFormat.ieeeDouble)
@@ -522,8 +522,7 @@ float nextDown(float x) @safe pure nothrow @nogc
@safe pure nothrow @nogc unittest
{
- import std.math : floatTraits, RealFormat;
- import std.math.traits : isIdentical;
+ import std.math.traits : floatTraits, RealFormat, isIdentical;
static if (floatTraits!(real).realFormat == RealFormat.ieeeExtended ||
floatTraits!(real).realFormat == RealFormat.ieeeDouble ||
@@ -865,7 +864,7 @@ real fma(real x, real y, real z) @safe pure nothrow @nogc { return (x * y) + z;
int feqrel(X)(const X x, const X y) @trusted pure nothrow @nogc
if (isFloatingPoint!(X))
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
import core.math : fabs;
/* Public Domain. Author: Don Clugston, 18 Aug 2005.
@@ -1495,7 +1494,7 @@ private template FloatingPointBaseType(T)
int cmp(T)(const(T) x, const(T) y) @nogc @trusted pure nothrow
if (isFloatingPoint!T)
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
alias F = floatTraits!T;
@@ -1723,7 +1722,7 @@ if (isFloatingPoint!T)
FloatingPointBitpattern!T extractBitpattern(T)(const(T) value) @trusted
if (isFloatingPoint!T)
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
T val = value;
FloatingPointBitpattern!T ret;
@@ -1895,7 +1894,7 @@ if (isFloatingPoint!T)
@safe pure unittest
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
alias F = floatTraits!real;
static if (F.realFormat == RealFormat.ieeeExtended)
@@ -1946,7 +1945,7 @@ if (isFloatingPoint!T)
@safe pure unittest
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
import std.math.exponential : log2;
alias F = floatTraits!real;
diff --git a/libphobos/src/std/math/package.d b/libphobos/src/std/math/package.d
index 614f4d3..0d1ecc3 100644
--- a/libphobos/src/std/math/package.d
+++ b/libphobos/src/std/math/package.d
@@ -321,169 +321,3 @@ else
static assert(real.mant_dig == 53 || real.mant_dig == 113,
"Only 64-bit and 128-bit reals are supported for BigEndian CPUs.");
}
-
-// Underlying format exposed through floatTraits
-enum RealFormat
-{
- ieeeHalf,
- ieeeSingle,
- ieeeDouble,
- ieeeExtended, // x87 80-bit real
- ieeeExtended53, // x87 real rounded to precision of double.
- ibmExtended, // IBM 128-bit extended
- ieeeQuadruple,
-}
-
-// Constants used for extracting the components of the representation.
-// They supplement the built-in floating point properties.
-template floatTraits(T)
-{
- import std.traits : Unqual;
-
- // EXPMASK is a ushort mask to select the exponent portion (without sign)
- // EXPSHIFT is the number of bits the exponent is left-shifted by in its ushort
- // EXPBIAS is the exponent bias - 1 (exp == EXPBIAS yields ×2^-1).
- // EXPPOS_SHORT is the index of the exponent when represented as a ushort array.
- // SIGNPOS_BYTE is the index of the sign when represented as a ubyte array.
- // RECIP_EPSILON is the value such that (smallest_subnormal) * RECIP_EPSILON == T.min_normal
- enum Unqual!T RECIP_EPSILON = (1/T.epsilon);
- static if (T.mant_dig == 24)
- {
- // Single precision float
- enum ushort EXPMASK = 0x7F80;
- enum ushort EXPSHIFT = 7;
- enum ushort EXPBIAS = 0x3F00;
- enum uint EXPMASK_INT = 0x7F80_0000;
- enum uint MANTISSAMASK_INT = 0x007F_FFFF;
- enum realFormat = RealFormat.ieeeSingle;
- version (LittleEndian)
- {
- enum EXPPOS_SHORT = 1;
- enum SIGNPOS_BYTE = 3;
- }
- else
- {
- enum EXPPOS_SHORT = 0;
- enum SIGNPOS_BYTE = 0;
- }
- }
- else static if (T.mant_dig == 53)
- {
- static if (T.sizeof == 8)
- {
- // Double precision float, or real == double
- enum ushort EXPMASK = 0x7FF0;
- enum ushort EXPSHIFT = 4;
- enum ushort EXPBIAS = 0x3FE0;
- enum uint EXPMASK_INT = 0x7FF0_0000;
- enum uint MANTISSAMASK_INT = 0x000F_FFFF; // for the MSB only
- enum ulong MANTISSAMASK_LONG = 0x000F_FFFF_FFFF_FFFF;
- enum realFormat = RealFormat.ieeeDouble;
- version (LittleEndian)
- {
- enum EXPPOS_SHORT = 3;
- enum SIGNPOS_BYTE = 7;
- }
- else
- {
- enum EXPPOS_SHORT = 0;
- enum SIGNPOS_BYTE = 0;
- }
- }
- else static if (T.sizeof == 12)
- {
- // Intel extended real80 rounded to double
- enum ushort EXPMASK = 0x7FFF;
- enum ushort EXPSHIFT = 0;
- enum ushort EXPBIAS = 0x3FFE;
- enum realFormat = RealFormat.ieeeExtended53;
- version (LittleEndian)
- {
- enum EXPPOS_SHORT = 4;
- enum SIGNPOS_BYTE = 9;
- }
- else
- {
- enum EXPPOS_SHORT = 0;
- enum SIGNPOS_BYTE = 0;
- }
- }
- else
- static assert(false, "No traits support for " ~ T.stringof);
- }
- else static if (T.mant_dig == 64)
- {
- // Intel extended real80
- enum ushort EXPMASK = 0x7FFF;
- enum ushort EXPSHIFT = 0;
- enum ushort EXPBIAS = 0x3FFE;
- enum realFormat = RealFormat.ieeeExtended;
- version (LittleEndian)
- {
- enum EXPPOS_SHORT = 4;
- enum SIGNPOS_BYTE = 9;
- }
- else
- {
- enum EXPPOS_SHORT = 0;
- enum SIGNPOS_BYTE = 0;
- }
- }
- else static if (T.mant_dig == 113)
- {
- // Quadruple precision float
- enum ushort EXPMASK = 0x7FFF;
- enum ushort EXPSHIFT = 0;
- enum ushort EXPBIAS = 0x3FFE;
- enum realFormat = RealFormat.ieeeQuadruple;
- version (LittleEndian)
- {
- enum EXPPOS_SHORT = 7;
- enum SIGNPOS_BYTE = 15;
- }
- else
- {
- enum EXPPOS_SHORT = 0;
- enum SIGNPOS_BYTE = 0;
- }
- }
- else static if (T.mant_dig == 106)
- {
- // IBM Extended doubledouble
- enum ushort EXPMASK = 0x7FF0;
- enum ushort EXPSHIFT = 4;
- enum realFormat = RealFormat.ibmExtended;
-
- // For IBM doubledouble the larger magnitude double comes first.
- // It's really a double[2] and arrays don't index differently
- // between little and big-endian targets.
- enum DOUBLEPAIR_MSB = 0;
- enum DOUBLEPAIR_LSB = 1;
-
- // The exponent/sign byte is for most significant part.
- version (LittleEndian)
- {
- enum EXPPOS_SHORT = 3;
- enum SIGNPOS_BYTE = 7;
- }
- else
- {
- enum EXPPOS_SHORT = 0;
- enum SIGNPOS_BYTE = 0;
- }
- }
- else
- static assert(false, "No traits support for " ~ T.stringof);
-}
-
-// These apply to all floating-point types
-version (LittleEndian)
-{
- enum MANTISSA_LSB = 0;
- enum MANTISSA_MSB = 1;
-}
-else
-{
- enum MANTISSA_LSB = 1;
- enum MANTISSA_MSB = 0;
-}
diff --git a/libphobos/src/std/math/rounding.d b/libphobos/src/std/math/rounding.d
index 7dbe89b..f6654fc 100644
--- a/libphobos/src/std/math/rounding.d
+++ b/libphobos/src/std/math/rounding.d
@@ -551,7 +551,7 @@ long lrint(real x) @trusted pure nothrow @nogc
}
else
{
- import std.math : floatTraits, RealFormat, MANTISSA_MSB, MANTISSA_LSB;
+ import std.math.traits : floatTraits, RealFormat, MANTISSA_MSB, MANTISSA_LSB;
alias F = floatTraits!(real);
static if (F.realFormat == RealFormat.ieeeDouble)
@@ -896,7 +896,7 @@ long rndtol(float x) @safe pure nothrow @nogc { return rndtol(cast(real) x); }
// Helper for floor/ceil
T floorImpl(T)(const T x) @trusted pure nothrow @nogc
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
alias F = floatTraits!(T);
// Take care not to trigger library calls from the compiler,
diff --git a/libphobos/src/std/math/traits.d b/libphobos/src/std/math/traits.d
index 2841bad..81ab1b7 100644
--- a/libphobos/src/std/math/traits.d
+++ b/libphobos/src/std/math/traits.d
@@ -137,7 +137,7 @@ if (isFloatingPoint!(X))
*/
bool isFinite(X)(X x) @trusted pure nothrow @nogc
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
static if (__traits(isFloating, X))
if (__ctfe)
@@ -202,7 +202,7 @@ bool isFinite(X)(X x) @trusted pure nothrow @nogc
*/
bool isNormal(X)(X x) @trusted pure nothrow @nogc
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
static if (__traits(isFloating, X))
if (__ctfe)
@@ -264,7 +264,7 @@ bool isNormal(X)(X x) @trusted pure nothrow @nogc
*/
bool isSubnormal(X)(X x) @trusted pure nothrow @nogc
{
- import std.math : floatTraits, RealFormat, MANTISSA_MSB, MANTISSA_LSB;
+ import std.math.traits : floatTraits, RealFormat, MANTISSA_MSB, MANTISSA_LSB;
static if (__traits(isFloating, X))
if (__ctfe)
@@ -344,7 +344,7 @@ bool isSubnormal(X)(X x) @trusted pure nothrow @nogc
bool isInfinity(X)(X x) @nogc @trusted pure nothrow
if (isFloatingPoint!(X))
{
- import std.math : floatTraits, RealFormat, MANTISSA_MSB, MANTISSA_LSB;
+ import std.math.traits : floatTraits, RealFormat, MANTISSA_MSB, MANTISSA_LSB;
alias F = floatTraits!(X);
static if (F.realFormat == RealFormat.ieeeSingle)
@@ -466,7 +466,7 @@ if (isFloatingPoint!(X))
*/
bool isIdentical(real x, real y) @trusted pure nothrow @nogc
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
// We're doing a bitwise comparison so the endianness is irrelevant.
long* pxs = cast(long *)&x;
@@ -510,7 +510,7 @@ bool isIdentical(real x, real y) @trusted pure nothrow @nogc
*/
int signbit(X)(X x) @nogc @trusted pure nothrow
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
if (__ctfe)
{
@@ -594,7 +594,7 @@ Returns:
R copysign(R, X)(R to, X from) @trusted pure nothrow @nogc
if (isFloatingPoint!(R) && isFloatingPoint!(X))
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
if (__ctfe)
{
@@ -851,3 +851,168 @@ if (isNumeric!X)
}}
}
+// Underlying format exposed through floatTraits
+enum RealFormat
+{
+ ieeeHalf,
+ ieeeSingle,
+ ieeeDouble,
+ ieeeExtended, // x87 80-bit real
+ ieeeExtended53, // x87 real rounded to precision of double.
+ ibmExtended, // IBM 128-bit extended
+ ieeeQuadruple,
+}
+
+// Constants used for extracting the components of the representation.
+// They supplement the built-in floating point properties.
+template floatTraits(T)
+{
+ import std.traits : Unqual;
+
+ // EXPMASK is a ushort mask to select the exponent portion (without sign)
+ // EXPSHIFT is the number of bits the exponent is left-shifted by in its ushort
+ // EXPBIAS is the exponent bias - 1 (exp == EXPBIAS yields ×2^-1).
+ // EXPPOS_SHORT is the index of the exponent when represented as a ushort array.
+ // SIGNPOS_BYTE is the index of the sign when represented as a ubyte array.
+ // RECIP_EPSILON is the value such that (smallest_subnormal) * RECIP_EPSILON == T.min_normal
+ enum Unqual!T RECIP_EPSILON = (1/T.epsilon);
+ static if (T.mant_dig == 24)
+ {
+ // Single precision float
+ enum ushort EXPMASK = 0x7F80;
+ enum ushort EXPSHIFT = 7;
+ enum ushort EXPBIAS = 0x3F00;
+ enum uint EXPMASK_INT = 0x7F80_0000;
+ enum uint MANTISSAMASK_INT = 0x007F_FFFF;
+ enum realFormat = RealFormat.ieeeSingle;
+ version (LittleEndian)
+ {
+ enum EXPPOS_SHORT = 1;
+ enum SIGNPOS_BYTE = 3;
+ }
+ else
+ {
+ enum EXPPOS_SHORT = 0;
+ enum SIGNPOS_BYTE = 0;
+ }
+ }
+ else static if (T.mant_dig == 53)
+ {
+ static if (T.sizeof == 8)
+ {
+ // Double precision float, or real == double
+ enum ushort EXPMASK = 0x7FF0;
+ enum ushort EXPSHIFT = 4;
+ enum ushort EXPBIAS = 0x3FE0;
+ enum uint EXPMASK_INT = 0x7FF0_0000;
+ enum uint MANTISSAMASK_INT = 0x000F_FFFF; // for the MSB only
+ enum ulong MANTISSAMASK_LONG = 0x000F_FFFF_FFFF_FFFF;
+ enum realFormat = RealFormat.ieeeDouble;
+ version (LittleEndian)
+ {
+ enum EXPPOS_SHORT = 3;
+ enum SIGNPOS_BYTE = 7;
+ }
+ else
+ {
+ enum EXPPOS_SHORT = 0;
+ enum SIGNPOS_BYTE = 0;
+ }
+ }
+ else static if (T.sizeof == 12)
+ {
+ // Intel extended real80 rounded to double
+ enum ushort EXPMASK = 0x7FFF;
+ enum ushort EXPSHIFT = 0;
+ enum ushort EXPBIAS = 0x3FFE;
+ enum realFormat = RealFormat.ieeeExtended53;
+ version (LittleEndian)
+ {
+ enum EXPPOS_SHORT = 4;
+ enum SIGNPOS_BYTE = 9;
+ }
+ else
+ {
+ enum EXPPOS_SHORT = 0;
+ enum SIGNPOS_BYTE = 0;
+ }
+ }
+ else
+ static assert(false, "No traits support for " ~ T.stringof);
+ }
+ else static if (T.mant_dig == 64)
+ {
+ // Intel extended real80
+ enum ushort EXPMASK = 0x7FFF;
+ enum ushort EXPSHIFT = 0;
+ enum ushort EXPBIAS = 0x3FFE;
+ enum realFormat = RealFormat.ieeeExtended;
+ version (LittleEndian)
+ {
+ enum EXPPOS_SHORT = 4;
+ enum SIGNPOS_BYTE = 9;
+ }
+ else
+ {
+ enum EXPPOS_SHORT = 0;
+ enum SIGNPOS_BYTE = 0;
+ }
+ }
+ else static if (T.mant_dig == 113)
+ {
+ // Quadruple precision float
+ enum ushort EXPMASK = 0x7FFF;
+ enum ushort EXPSHIFT = 0;
+ enum ushort EXPBIAS = 0x3FFE;
+ enum realFormat = RealFormat.ieeeQuadruple;
+ version (LittleEndian)
+ {
+ enum EXPPOS_SHORT = 7;
+ enum SIGNPOS_BYTE = 15;
+ }
+ else
+ {
+ enum EXPPOS_SHORT = 0;
+ enum SIGNPOS_BYTE = 0;
+ }
+ }
+ else static if (T.mant_dig == 106)
+ {
+ // IBM Extended doubledouble
+ enum ushort EXPMASK = 0x7FF0;
+ enum ushort EXPSHIFT = 4;
+ enum realFormat = RealFormat.ibmExtended;
+
+ // For IBM doubledouble the larger magnitude double comes first.
+ // It's really a double[2] and arrays don't index differently
+ // between little and big-endian targets.
+ enum DOUBLEPAIR_MSB = 0;
+ enum DOUBLEPAIR_LSB = 1;
+
+ // The exponent/sign byte is for most significant part.
+ version (LittleEndian)
+ {
+ enum EXPPOS_SHORT = 3;
+ enum SIGNPOS_BYTE = 7;
+ }
+ else
+ {
+ enum EXPPOS_SHORT = 0;
+ enum SIGNPOS_BYTE = 0;
+ }
+ }
+ else
+ static assert(false, "No traits support for " ~ T.stringof);
+}
+
+// These apply to all floating-point types
+version (LittleEndian)
+{
+ enum MANTISSA_LSB = 0;
+ enum MANTISSA_MSB = 1;
+}
+else
+{
+ enum MANTISSA_LSB = 1;
+ enum MANTISSA_MSB = 0;
+}
diff --git a/libphobos/src/std/math/trigonometry.d b/libphobos/src/std/math/trigonometry.d
index a3d04c6..4f5f5c5 100644
--- a/libphobos/src/std/math/trigonometry.d
+++ b/libphobos/src/std/math/trigonometry.d
@@ -307,7 +307,7 @@ Lret:
private T tanImpl(T)(T x) @safe pure nothrow @nogc
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
import std.math.constants : PI, PI_4;
import std.math.rounding : floor;
import std.math.algebraic : poly;
@@ -675,8 +675,7 @@ float atan(float x) @safe pure nothrow @nogc { return __ctfe ? cast(float) atan(
private T atanImpl(T)(T x) @safe pure nothrow @nogc
{
- import std.math : floatTraits, RealFormat;
- import std.math.traits : copysign, isInfinity, signbit;
+ import std.math.traits : floatTraits, RealFormat, copysign, isInfinity, signbit;
import std.math.constants : PI_2, PI_4;
import std.math.algebraic : poly;
diff --git a/libphobos/src/std/mmfile.d b/libphobos/src/std/mmfile.d
index f8f8a90..b2cab31 100644
--- a/libphobos/src/std/mmfile.d
+++ b/libphobos/src/std/mmfile.d
@@ -2,10 +2,22 @@
/**
* Read and write memory mapped files.
+ *
+ * Memory mapped files are a mechanism in operating systems that allows
+ * file access through virtual memory. After opening a file with `MmFile`,
+ * the contents can be read from or written to with standard slice / pointer operations.
+ * Changes to the memory are automatically reflected in the underlying file.
+ *
+ * Memory mapping can increase I/O performance of large files, compared to buffered
+ * read / write operations from `std.file` and `std.stdio`. However, I/O errors are
+ * not handled as safely: when for example the disk that the file is on gets removed,
+ * reading from it may result in a segfault.
+ *
* Copyright: Copyright The D Language Foundation 2004 - 2009.
* License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
* Authors: $(HTTP digitalmars.com, Walter Bright),
* Matthew Wilson
+ * References: $(LINK https://en.wikipedia.org/wiki/Memory-mapped_file)
* Source: $(PHOBOSSRC std/mmfile.d)
*
* $(SCRIPT inhibitQuickIndex = 1;)
@@ -612,23 +624,47 @@ private:
{
static assert(0);
}
+}
+
+/// Read an existing file
+@system unittest
+{
+ import std.file;
+ std.file.write(deleteme, "hello"); // deleteme is a temporary filename
+ scope(exit) remove(deleteme);
+
+ // Use a scope class so the file will be closed at the end of this function
+ scope mmfile = new MmFile(deleteme);
+
+ assert(mmfile.length == "hello".length);
+
+ // Access file contents with the slice operator
+ // This is typed as `void[]`, so cast to `char[]` or `ubyte[]` to use it
+ const data = cast(const(char)[]) mmfile[];
+
+ // At this point, the file content may not have been read yet.
+ // In that case, the following memory access will intentionally
+ // trigger a page fault, causing the kernel to load the file contents
+ assert(data[0 .. 5] == "hello");
+}
+
+/// Write a new file
+@system unittest
+{
+ import std.file;
+ scope(exit) remove(deleteme);
+
+ scope mmfile = new MmFile(deleteme, MmFile.Mode.readWriteNew, 5, null);
+ assert(mmfile.length == 5);
+
+ auto data = cast(ubyte[]) mmfile[];
+
+ // This write to memory will be reflected in the file contents
+ data[] = '\n';
+
+ mmfile.flush();
- // Report error, where errno gives the error number
- // void errNo()
- // {
- // version (Windows)
- // {
- // throw new FileException(filename, GetLastError());
- // }
- // else version (linux)
- // {
- // throw new FileException(filename, errno);
- // }
- // else
- // {
- // static assert(0);
- // }
- // }
+ assert(std.file.read(deleteme) == "\n\n\n\n\n");
}
@system unittest
diff --git a/libphobos/src/std/regex/internal/backtracking.d b/libphobos/src/std/regex/internal/backtracking.d
index ac73f70..a488e06 100644
--- a/libphobos/src/std/regex/internal/backtracking.d
+++ b/libphobos/src/std/regex/internal/backtracking.d
@@ -682,7 +682,7 @@ final:
while (prevStack()) {}
return re.ir[pc].data;
default:
- debug printBytecode(re.ir[0..$]);
+ debug(std_regex_debug) printBytecode(re.ir[0..$]);
assert(0);
L_backtrack:
if (!popState())
diff --git a/libphobos/src/std/regex/internal/ir.d b/libphobos/src/std/regex/internal/ir.d
index 069d75f..04b902f 100644
--- a/libphobos/src/std/regex/internal/ir.d
+++ b/libphobos/src/std/regex/internal/ir.d
@@ -403,7 +403,7 @@ struct Group(DataIndex)
}
//debugging tool, prints out instruction along with opcodes
-@trusted string disassemble(in Bytecode[] irb, uint pc, in NamedGroup[] dict=[])
+debug(std_regex_parser) @trusted string disassemble(in Bytecode[] irb, uint pc, in NamedGroup[] dict=[])
{
import std.array : appender;
import std.format.write : formattedWrite;
@@ -467,7 +467,7 @@ struct Group(DataIndex)
}
//disassemble the whole chunk
-@trusted void printBytecode()(in Bytecode[] slice, in NamedGroup[] dict=[])
+debug(std_regex_parser) @trusted void printBytecode()(in Bytecode[] slice, in NamedGroup[] dict=[])
{
import std.stdio : writeln;
for (uint pc=0; pc<slice.length; pc += slice[pc].length)
diff --git a/libphobos/src/std/typecons.d b/libphobos/src/std/typecons.d
index 67a1ede..13ae294 100644
--- a/libphobos/src/std/typecons.d
+++ b/libphobos/src/std/typecons.d
@@ -3256,11 +3256,19 @@ struct Nullable(T)
* Params:
* value = The value to initialize this `Nullable` with.
*/
- this(inout T value) inout
- {
- _value.payload = value;
- _isNull = false;
- }
+ static if (isCopyable!T)
+ this(inout T value) inout
+ {
+ _value.payload = value;
+ _isNull = false;
+ }
+ else
+ this(T value) inout
+ {
+ import std.algorithm.mutation : move;
+ _value.payload = move(value);
+ _isNull = false;
+ }
static if (hasElaborateDestructor!T)
{
@@ -3273,6 +3281,9 @@ struct Nullable(T)
}
}
+ static if (!isCopyable!T)
+ @disable this(this);
+ else
static if (__traits(hasPostblit, T))
{
this(this)
@@ -3511,22 +3522,18 @@ struct Nullable(T)
* Params:
* value = A value of type `T` to assign to this `Nullable`.
*/
- Nullable opAssign()(T value)
+ ref Nullable opAssign()(T value) return
{
import std.algorithm.mutation : moveEmplace, move;
- // the lifetime of the value in copy shall be managed by
- // this Nullable, so we must avoid calling its destructor.
- auto copy = DontCallDestructorT(value);
-
if (_isNull)
{
// trusted since payload is known to be uninitialized.
- () @trusted { moveEmplace(copy.payload, _value.payload); }();
+ () @trusted { moveEmplace(value, _value.payload); }();
}
else
{
- move(copy.payload, _value.payload);
+ move(value, _value.payload);
}
_isNull = false;
return this;
@@ -3604,12 +3611,14 @@ struct Nullable(T)
alias back = front;
/// ditto
+ static if (isCopyable!T)
@property inout(typeof(this)) save() inout
{
return this;
}
/// ditto
+ static if (isCopyable!T)
inout(typeof(this)) opIndex(size_t[2] dim) inout
in (dim[0] <= length && dim[1] <= length && dim[1] >= dim[0])
{
@@ -4088,16 +4097,12 @@ auto nullable(T)(T t)
struct Test
{
- bool b;
-
- nothrow invariant { assert(b == true); }
-
SysTime _st;
static bool destroyed;
@disable this();
- this(bool b) { this.b = b; }
+ this(int _dummy) {}
~this() @safe { destroyed = true; }
// mustn't call opAssign on Test.init in Nullable!Test, because the invariant
@@ -4109,7 +4114,7 @@ auto nullable(T)(T t)
{
Nullable!Test nt;
- nt = Test(true);
+ nt = Test(1);
// destroy value
Test.destroyed = false;
@@ -10676,6 +10681,21 @@ unittest
assert(s2.get().b == 3);
}
+// https://issues.dlang.org/show_bug.cgi?id=24318
+@system unittest
+{
+ static struct S
+ {
+ @disable this(this);
+ int i;
+ }
+
+ Nullable!S s = S(1);
+ assert(s.get().i == 1);
+ s = S(2);
+ assert(s.get().i == 2);
+}
+
/// The old version of $(LREF SafeRefCounted), before $(LREF borrow) existed.
/// Old code may be relying on `@safe`ty of some of the member functions which
/// cannot be safe in the new scheme, and