libphobos: Merge upstream druntime 89f870b7, phobos e6907ff3e
Phobos changes: - Synchronize C bindings with the latest port fixes in upstream druntime. - Add Config.stderrPassThrough to std.process (PR98494). Reviewed-on: https://github.com/dlang/druntime/pull/3448 https://github.com/dlang/phobos/pull/7984 libphobos/ChangeLog: PR d/98494 * libdruntime/MERGE: Merge upstream druntime 89f870b7. * src/MERGE: Merge upstream phobos e6907ff3e.
This commit is contained in:
parent
6eae7549b8
commit
e19c638996
18 changed files with 525 additions and 214 deletions
|
@ -1,4 +1,4 @@
|
|||
1134b71039881464e9bf021836d82796b3a1fcfc
|
||||
89f870b76710a4cfa96f711bb5b14a7439c5c2a7
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
merge done from the dlang/druntime repository.
|
||||
|
|
|
@ -186,7 +186,18 @@ else version (Posix)
|
|||
}
|
||||
}
|
||||
|
||||
version (CRuntime_Microsoft)
|
||||
version (GNU)
|
||||
alias c_long_double = real;
|
||||
else version (LDC)
|
||||
alias c_long_double = real; // 64-bit real for MSVC targets
|
||||
else version (SDC)
|
||||
{
|
||||
version (X86)
|
||||
alias c_long_double = real;
|
||||
else version (X86_64)
|
||||
alias c_long_double = real;
|
||||
}
|
||||
else version (CRuntime_Microsoft)
|
||||
{
|
||||
/* long double is 64 bits, not 80 bits, but is mangled differently
|
||||
* than double. To distinguish double from long double, create a wrapper to represent
|
||||
|
@ -222,17 +233,6 @@ else version (DigitalMars)
|
|||
alias real c_long_double;
|
||||
}
|
||||
}
|
||||
else version (GNU)
|
||||
alias real c_long_double;
|
||||
else version (LDC)
|
||||
alias real c_long_double;
|
||||
else version (SDC)
|
||||
{
|
||||
version (X86)
|
||||
alias real c_long_double;
|
||||
else version (X86_64)
|
||||
alias real c_long_double;
|
||||
}
|
||||
|
||||
static assert(is(c_long_double), "c_long_double needs to be declared for this platform/architecture.");
|
||||
|
||||
|
@ -257,18 +257,9 @@ private struct _Complex(T)
|
|||
T im;
|
||||
}
|
||||
|
||||
version (Posix)
|
||||
{
|
||||
align(float.alignof) enum __c_complex_float : _Complex!float;
|
||||
align(double.alignof) enum __c_complex_double : _Complex!double;
|
||||
align(real.alignof) enum __c_complex_real : _Complex!real;
|
||||
}
|
||||
else
|
||||
{
|
||||
align(float.sizeof * 2) enum __c_complex_float : _Complex!float;
|
||||
align(double.sizeof * 2) enum __c_complex_double : _Complex!double;
|
||||
align(real.alignof) enum __c_complex_real : _Complex!real;
|
||||
}
|
||||
enum __c_complex_float : _Complex!float;
|
||||
enum __c_complex_double : _Complex!double;
|
||||
enum __c_complex_real : _Complex!c_long_double;
|
||||
|
||||
alias c_complex_float = __c_complex_float;
|
||||
alias c_complex_double = __c_complex_double;
|
||||
|
|
|
@ -424,6 +424,90 @@ else version (CRuntime_Microsoft) // fully supported since MSVCRT 12 (VS 2013) o
|
|||
pure int _fpclass(double x);
|
||||
}
|
||||
|
||||
version (MinGW)
|
||||
{
|
||||
enum
|
||||
{
|
||||
///
|
||||
FP_NAN = 0x0100,
|
||||
///
|
||||
FP_NORMAL = 0x0400,
|
||||
///
|
||||
FP_INFINITE = FP_NAN | FP_NORMAL,
|
||||
///
|
||||
FP_ZERO = 0x0400,
|
||||
///
|
||||
FP_SUBNORMAL = FP_NORMAL | FP_ZERO
|
||||
}
|
||||
|
||||
pure int __fpclassifyf(float x);
|
||||
pure int __fpclassify(double x);
|
||||
pure int __fpclassifyl(real x);
|
||||
|
||||
pure int __isnanf(float x);
|
||||
pure int __isnan(double x);
|
||||
pure int __isnanl(real x);
|
||||
|
||||
pure int __signbitf(float x);
|
||||
pure int __signbit(double x);
|
||||
pure int __signbitl(real x);
|
||||
|
||||
extern (D)
|
||||
{
|
||||
//int fpclassify(real-floating x);
|
||||
///
|
||||
extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x);
|
||||
///
|
||||
extern(C) pragma(mangle, "__fpclassify") pure int fpclassify(double x);
|
||||
///
|
||||
extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__fpclassify" : "__fpclassifyl")
|
||||
pure int fpclassify(real x);
|
||||
|
||||
//int isfinite(real-floating x);
|
||||
///
|
||||
pure int isfinite(float x) { return (fpclassify(x) & FP_NORMAL) == 0; }
|
||||
///
|
||||
pure int isfinite(double x) { return (fpclassify(x) & FP_NORMAL) == 0; }
|
||||
///
|
||||
pure int isfinite(real x) { return (fpclassify(x) & FP_NORMAL) == 0; }
|
||||
|
||||
//int isinf(real-floating x);
|
||||
///
|
||||
pure int isinf(float x) { return fpclassify(x) == FP_INFINITE; }
|
||||
///
|
||||
pure int isinf(double x) { return fpclassify(x) == FP_INFINITE; }
|
||||
///
|
||||
pure int isinf(real x) { return fpclassify(x) == FP_INFINITE; }
|
||||
|
||||
//int isnan(real-floating x);
|
||||
///
|
||||
extern(C) pragma(mangle, "__isnanf") pure int isnan(float x);
|
||||
///
|
||||
extern(C) pragma(mangle, "__isnan") pure int isnan(double x);
|
||||
///
|
||||
extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__isnan" : "__isnanl")
|
||||
pure int isnan(real x);
|
||||
|
||||
//int isnormal(real-floating x);
|
||||
///
|
||||
int isnormal(float x) { return fpclassify(x) == FP_NORMAL; }
|
||||
///
|
||||
int isnormal(double x) { return fpclassify(x) == FP_NORMAL; }
|
||||
///
|
||||
int isnormal(real x) { return fpclassify(x) == FP_NORMAL; }
|
||||
|
||||
//int signbit(real-floating x);
|
||||
///
|
||||
extern(C) pragma(mangle, "__signbitf") pure int signbit(float x);
|
||||
///
|
||||
extern(C) pragma(mangle, "__signbit") pure int signbit(double x);
|
||||
///
|
||||
extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__signbit" : "__signbitl")
|
||||
int signbit(real x);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
enum
|
||||
{
|
||||
///
|
||||
|
@ -438,78 +522,79 @@ else version (CRuntime_Microsoft) // fully supported since MSVCRT 12 (VS 2013) o
|
|||
FP_NAN = 2,
|
||||
}
|
||||
|
||||
extern(D)
|
||||
{
|
||||
//int fpclassify(real-floating x);
|
||||
///
|
||||
extern(C) pragma(mangle, "_fdclass") pure int fpclassify(float x);
|
||||
///
|
||||
extern(C) pragma(mangle, "_dclass") pure int fpclassify(double x);
|
||||
///
|
||||
pure int fpclassify()(real x)
|
||||
extern(D)
|
||||
{
|
||||
static if (real.sizeof == double.sizeof)
|
||||
return fpclassify(cast(double) x);
|
||||
else
|
||||
static assert(false, "fpclassify(real) not supported by MS C runtime");
|
||||
}
|
||||
//int fpclassify(real-floating x);
|
||||
///
|
||||
extern(C) pragma(mangle, "_fdclass") pure int fpclassify(float x);
|
||||
///
|
||||
extern(C) pragma(mangle, "_dclass") pure int fpclassify(double x);
|
||||
///
|
||||
pure int fpclassify()(real x)
|
||||
{
|
||||
static if (real.sizeof == double.sizeof)
|
||||
return fpclassify(cast(double) x);
|
||||
else
|
||||
static assert(false, "fpclassify(real) not supported by MS C runtime");
|
||||
}
|
||||
|
||||
//int isfinite(real-floating x);
|
||||
///
|
||||
pure int isfinite()(float x) { return fpclassify(x) <= 0; }
|
||||
///
|
||||
pure int isfinite()(double x) { return fpclassify(x) <= 0; }
|
||||
///
|
||||
pure int isfinite()(real x) { return fpclassify(x) <= 0; }
|
||||
//int isfinite(real-floating x);
|
||||
///
|
||||
pure int isfinite()(float x) { return fpclassify(x) <= 0; }
|
||||
///
|
||||
pure int isfinite()(double x) { return fpclassify(x) <= 0; }
|
||||
///
|
||||
pure int isfinite()(real x) { return fpclassify(x) <= 0; }
|
||||
|
||||
//int isinf(real-floating x);
|
||||
///
|
||||
pure int isinf()(float x) { return fpclassify(x) == FP_INFINITE; }
|
||||
///
|
||||
pure int isinf()(double x) { return fpclassify(x) == FP_INFINITE; }
|
||||
///
|
||||
pure int isinf()(real x) { return fpclassify(x) == FP_INFINITE; }
|
||||
//int isinf(real-floating x);
|
||||
///
|
||||
pure int isinf()(float x) { return fpclassify(x) == FP_INFINITE; }
|
||||
///
|
||||
pure int isinf()(double x) { return fpclassify(x) == FP_INFINITE; }
|
||||
///
|
||||
pure int isinf()(real x) { return fpclassify(x) == FP_INFINITE; }
|
||||
|
||||
//int isnan(real-floating x);
|
||||
version (none) // requires MSVCRT 12+ (VS 2013)
|
||||
{
|
||||
///
|
||||
pure int isnan(float x) { return fpclassify(x) == FP_NAN; }
|
||||
///
|
||||
pure int isnan(double x) { return fpclassify(x) == FP_NAN; }
|
||||
///
|
||||
pure int isnan(real x) { return fpclassify(x) == FP_NAN; }
|
||||
}
|
||||
else // for backward compatibility with older runtimes
|
||||
{
|
||||
///
|
||||
pure int isnan(float x) { version (Win64) return _isnanf(x); else return _isnan(cast(double) x); }
|
||||
///
|
||||
extern(C) pragma(mangle, "_isnan") pure int isnan(double x);
|
||||
///
|
||||
pure int isnan(real x) { return _isnan(cast(double) x); }
|
||||
}
|
||||
//int isnan(real-floating x);
|
||||
version (none) // requires MSVCRT 12+ (VS 2013)
|
||||
{
|
||||
///
|
||||
pure int isnan(float x) { return fpclassify(x) == FP_NAN; }
|
||||
///
|
||||
pure int isnan(double x) { return fpclassify(x) == FP_NAN; }
|
||||
///
|
||||
pure int isnan(real x) { return fpclassify(x) == FP_NAN; }
|
||||
}
|
||||
else // for backward compatibility with older runtimes
|
||||
{
|
||||
///
|
||||
pure int isnan(float x) { version (Win64) return _isnanf(x); else return _isnan(cast(double) x); }
|
||||
///
|
||||
extern(C) pragma(mangle, "_isnan") pure int isnan(double x);
|
||||
///
|
||||
pure int isnan(real x) { return _isnan(cast(double) x); }
|
||||
}
|
||||
|
||||
//int isnormal(real-floating x);
|
||||
///
|
||||
pure int isnormal()(float x) { return fpclassify(x) == FP_NORMAL; }
|
||||
///
|
||||
pure int isnormal()(double x) { return fpclassify(x) == FP_NORMAL; }
|
||||
///
|
||||
pure int isnormal()(real x) { return fpclassify(x) == FP_NORMAL; }
|
||||
//int isnormal(real-floating x);
|
||||
///
|
||||
pure int isnormal()(float x) { return fpclassify(x) == FP_NORMAL; }
|
||||
///
|
||||
pure int isnormal()(double x) { return fpclassify(x) == FP_NORMAL; }
|
||||
///
|
||||
pure int isnormal()(real x) { return fpclassify(x) == FP_NORMAL; }
|
||||
|
||||
//int signbit(real-floating x);
|
||||
///
|
||||
extern(C) pragma(mangle, "_fdsign") pure int signbit(float x);
|
||||
///
|
||||
extern(C) pragma(mangle, "_dsign") pure int signbit(double x);
|
||||
///
|
||||
pure int signbit()(real x)
|
||||
{
|
||||
static if (real.sizeof == double.sizeof)
|
||||
return signbit(cast(double) x);
|
||||
else
|
||||
return (cast(short*)&(x))[4] & 0x8000;
|
||||
//int signbit(real-floating x);
|
||||
///
|
||||
extern(C) pragma(mangle, "_fdsign") pure int signbit(float x);
|
||||
///
|
||||
extern(C) pragma(mangle, "_dsign") pure int signbit(double x);
|
||||
///
|
||||
pure int signbit()(real x)
|
||||
{
|
||||
static if (real.sizeof == double.sizeof)
|
||||
return signbit(cast(double) x);
|
||||
else
|
||||
return (cast(short*)&(x))[4] & 0x8000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -835,88 +920,6 @@ else version (CRuntime_UClibc)
|
|||
int signbit(real x);
|
||||
}
|
||||
}
|
||||
else version (MinGW)
|
||||
{
|
||||
enum
|
||||
{
|
||||
///
|
||||
FP_NAN = 0x0100,
|
||||
///
|
||||
FP_NORMAL = 0x0400,
|
||||
///
|
||||
FP_INFINITE = FP_NAN | FP_NORMAL,
|
||||
///
|
||||
FP_ZERO = 0x0400,
|
||||
///
|
||||
FP_SUBNORMAL = FP_NORMAL | FP_ZERO
|
||||
}
|
||||
|
||||
pure int __fpclassifyf(float x);
|
||||
pure int __fpclassify(double x);
|
||||
pure int __fpclassifyl(real x);
|
||||
|
||||
pure int __isnanf(float x);
|
||||
pure int __isnan(double x);
|
||||
pure int __isnanl(real x);
|
||||
|
||||
pure int __signbitf(float x);
|
||||
pure int __signbit(double x);
|
||||
pure int __signbitl(real x);
|
||||
|
||||
extern (D)
|
||||
{
|
||||
//int fpclassify(real-floating x);
|
||||
///
|
||||
extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x);
|
||||
///
|
||||
extern(C) pragma(mangle, "__fpclassify") pure int fpclassify(double x);
|
||||
///
|
||||
extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__fpclassify" : "__fpclassifyl")
|
||||
pure int fpclassify(real x);
|
||||
|
||||
//int isfinite(real-floating x);
|
||||
///
|
||||
pure int isfinite(float x) { return (fpclassify(x) & FP_NORMAL) == 0; }
|
||||
///
|
||||
pure int isfinite(double x) { return (fpclassify(x) & FP_NORMAL) == 0; }
|
||||
///
|
||||
pure int isfinite(real x) { return (fpclassify(x) & FP_NORMAL) == 0; }
|
||||
|
||||
//int isinf(real-floating x);
|
||||
///
|
||||
pure int isinf(float x) { return fpclassify(x) == FP_INFINITE; }
|
||||
///
|
||||
pure int isinf(double x) { return fpclassify(x) == FP_INFINITE; }
|
||||
///
|
||||
pure int isinf(real x) { return fpclassify(x) == FP_INFINITE; }
|
||||
|
||||
//int isnan(real-floating x);
|
||||
///
|
||||
extern(C) pragma(mangle, "__isnanf") pure int isnan(float x);
|
||||
///
|
||||
extern(C) pragma(mangle, "__isnan") pure int isnan(double x);
|
||||
///
|
||||
extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__isnan" : "__isnanl")
|
||||
pure int isnan(real x);
|
||||
|
||||
//int isnormal(real-floating x);
|
||||
///
|
||||
int isnormal(float x) { return fpclassify(x) == FP_NORMAL; }
|
||||
///
|
||||
int isnormal(double x) { return fpclassify(x) == FP_NORMAL; }
|
||||
///
|
||||
int isnormal(real x) { return fpclassify(x) == FP_NORMAL; }
|
||||
|
||||
//int signbit(real-floating x);
|
||||
///
|
||||
extern(C) pragma(mangle, "__signbitf") pure int signbit(float x);
|
||||
///
|
||||
extern(C) pragma(mangle, "__signbit") pure int signbit(double x);
|
||||
///
|
||||
extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__signbit" : "__signbitl")
|
||||
int signbit(real x);
|
||||
}
|
||||
}
|
||||
else version (Darwin)
|
||||
{
|
||||
enum
|
||||
|
@ -1166,7 +1169,7 @@ else version (OpenBSD)
|
|||
FP_FAST_FMAL = 1,
|
||||
}
|
||||
|
||||
pure int __fpclassifyd(double);
|
||||
pure int __fpclassify(double);
|
||||
pure int __fpclassifyf(float);
|
||||
pure int __fpclassifyl(real);
|
||||
pure int __isfinitef(float);
|
||||
|
@ -1188,7 +1191,7 @@ else version (OpenBSD)
|
|||
///
|
||||
extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x);
|
||||
///
|
||||
extern(C) pragma(mangle, "__fpclassifyd") pure int fpclassify(double x);
|
||||
extern(C) pragma(mangle, "__fpclassify") pure int fpclassify(double x);
|
||||
///
|
||||
extern(C) pragma(mangle, "__fpclassifyl") pure int fpclassify(real x);
|
||||
|
||||
|
|
|
@ -1347,7 +1347,7 @@ version (CRuntime_DigitalMars)
|
|||
///
|
||||
pure int fileno()(FILE* stream) { return stream._file; }
|
||||
}
|
||||
///
|
||||
///
|
||||
pragma(printf)
|
||||
int _snprintf(scope char* s, size_t n, scope const char* fmt, scope const ...);
|
||||
///
|
||||
|
@ -1358,6 +1358,26 @@ version (CRuntime_DigitalMars)
|
|||
int _vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
|
||||
///
|
||||
alias _vsnprintf vsnprintf;
|
||||
|
||||
//
|
||||
// Digital Mars under-the-hood C I/O functions. Uses _iobuf* for the
|
||||
// unshared version of FILE*, usable when the FILE is locked.
|
||||
//
|
||||
|
||||
///
|
||||
int _fputc_nlock(int c, _iobuf* fp);
|
||||
///
|
||||
int _fputwc_nlock(int c, _iobuf* fp);
|
||||
///
|
||||
int _fgetc_nlock(_iobuf* fp);
|
||||
///
|
||||
int _fgetwc_nlock(_iobuf* fp);
|
||||
///
|
||||
int __fp_lock(FILE* fp);
|
||||
///
|
||||
void __fp_unlock(FILE* fp);
|
||||
///
|
||||
int setmode(int fd, int mode);
|
||||
}
|
||||
else version (CRuntime_Microsoft)
|
||||
{
|
||||
|
@ -1410,16 +1430,31 @@ else version (CRuntime_Microsoft)
|
|||
int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
|
||||
}
|
||||
|
||||
///
|
||||
int _fputc_nolock(int c, FILE *fp);
|
||||
///
|
||||
int _fgetc_nolock(FILE *fp);
|
||||
//
|
||||
// Microsoft under-the-hood C I/O functions. Uses _iobuf* for the unshared
|
||||
// version of FILE*, usable when the FILE is locked.
|
||||
//
|
||||
import core.stdc.stddef : wchar_t;
|
||||
import core.stdc.wchar_ : wint_t;
|
||||
|
||||
///
|
||||
int _lock_file(FILE *fp);
|
||||
int _fputc_nolock(int c, _iobuf* fp);
|
||||
///
|
||||
int _unlock_file(FILE *fp);
|
||||
|
||||
int _fgetc_nolock(_iobuf* fp);
|
||||
///
|
||||
wint_t _fputwc_nolock(wchar_t c, _iobuf* fp);
|
||||
///
|
||||
wint_t _fgetwc_nolock(_iobuf* fp);
|
||||
///
|
||||
void _lock_file(FILE* fp);
|
||||
///
|
||||
void _unlock_file(FILE* fp);
|
||||
///
|
||||
int _setmode(int fd, int mode);
|
||||
///
|
||||
int _fseeki64(FILE* stream, long offset, int origin);
|
||||
///
|
||||
long _ftelli64(FILE* stream);
|
||||
///
|
||||
intptr_t _get_osfhandle(int fd);
|
||||
///
|
||||
|
@ -1448,6 +1483,23 @@ else version (CRuntime_Glibc)
|
|||
///
|
||||
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 (Darwin)
|
||||
{
|
||||
|
@ -1907,6 +1959,22 @@ version (Windows)
|
|||
O_TEXT = _O_TEXT, ///
|
||||
_O_BINARY = 0x8000, ///
|
||||
O_BINARY = _O_BINARY, ///
|
||||
_O_WTEXT = 0x10000, ///
|
||||
_O_U16TEXT = 0x20000, ///
|
||||
_O_U8TEXT = 0x40000, ///
|
||||
_O_ACCMODE = (_O_RDONLY|_O_WRONLY|_O_RDWR), ///
|
||||
O_ACCMODE = _O_ACCMODE, ///
|
||||
_O_RAW = _O_BINARY, ///
|
||||
O_RAW = _O_BINARY, ///
|
||||
_O_NOINHERIT = 0x0080, ///
|
||||
O_NOINHERIT = _O_NOINHERIT, ///
|
||||
_O_TEMPORARY = 0x0040, ///
|
||||
O_TEMPORARY = _O_TEMPORARY, ///
|
||||
_O_SHORT_LIVED = 0x1000, ///
|
||||
_O_SEQUENTIAL = 0x0020, ///
|
||||
O_SEQUENTIAL = _O_SEQUENTIAL, ///
|
||||
_O_RANDOM = 0x0010, ///
|
||||
O_RANDOM = _O_RANDOM, ///
|
||||
}
|
||||
|
||||
enum
|
||||
|
|
|
@ -121,19 +121,22 @@ ulong strtoull(scope inout(char)* nptr, scope inout(char)** endptr, int base);
|
|||
|
||||
version (CRuntime_Microsoft)
|
||||
{
|
||||
// strtold exists starting from VS2013, so we give it D linkage to avoid link errors
|
||||
///
|
||||
extern (D) real strtold(scope inout(char)* nptr, inout(char)** endptr)
|
||||
{ // Fake it 'till we make it
|
||||
return strtod(nptr, endptr);
|
||||
version (MinGW)
|
||||
{
|
||||
///
|
||||
real __mingw_strtold(scope inout(char)* nptr, scope inout(char)** endptr);
|
||||
///
|
||||
alias __mingw_strtold strtold;
|
||||
}
|
||||
else
|
||||
{
|
||||
// strtold exists starting from VS2013, so we give it D linkage to avoid link errors
|
||||
///
|
||||
extern (D) real strtold(scope inout(char)* nptr, inout(char)** endptr)
|
||||
{ // Fake it 'till we make it
|
||||
return strtod(nptr, endptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
else version (MinGW)
|
||||
{
|
||||
///
|
||||
real __mingw_strtold(scope inout(char)* nptr, scope inout(char)** endptr);
|
||||
///
|
||||
alias __mingw_strtold strtold;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1285,6 +1285,13 @@ else
|
|||
alias core.stdc.math.fabs fabs;
|
||||
version (CRuntime_Microsoft)
|
||||
{
|
||||
version (MinGW)
|
||||
{
|
||||
///
|
||||
alias core.stdc.math.fabsf fabs;
|
||||
///
|
||||
alias core.stdc.math.fabsl fabs;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -38,6 +38,10 @@ version (AArch64)
|
|||
version = AnyARM;
|
||||
version (ARM)
|
||||
version = AnyARM;
|
||||
version (PPC)
|
||||
version = AnyPPC;
|
||||
version (PPC64)
|
||||
version = AnyPPC;
|
||||
|
||||
version (i386)
|
||||
{
|
||||
|
@ -235,3 +239,65 @@ else version (AnyARM)
|
|||
kern_return_t thread_resume(thread_act_t);
|
||||
kern_return_t thread_get_state(thread_act_t, thread_state_flavor_t, thread_state_t*, mach_msg_type_number_t*);
|
||||
}
|
||||
else version (AnyPPC)
|
||||
{
|
||||
alias thread_act_t = mach_port_t;
|
||||
alias thread_state_t = void;
|
||||
alias thread_state_flavor_t = int;
|
||||
alias mach_msg_type_number_t = natural_t;
|
||||
|
||||
enum
|
||||
{
|
||||
PPC_THREAD_STATE = 1,
|
||||
PPC_FLOAT_STATE = 2,
|
||||
PPC_EXCEPTION_STATE = 3,
|
||||
PPC_VECTOR_STATE = 4,
|
||||
PPC_THREAD_STATE64 = 5,
|
||||
PPC_EXCEPTION_STATE64 = 6,
|
||||
THREAD_STATE_NONE = 7
|
||||
}
|
||||
|
||||
struct ppc_thread_state_t
|
||||
{
|
||||
uint srr0; /// Instruction address register (PC)
|
||||
uint srr1; /// Machine state register (supervisor)
|
||||
uint[32] r; /// General purpose register r0-r31
|
||||
uint cr; /// Condition register
|
||||
uint xer; /// User's integer exception register
|
||||
uint lr; /// Link register
|
||||
uint ctr; /// Count register
|
||||
uint mq; /// MQ register (601 only)
|
||||
uint vrsave; /// Vector save register
|
||||
}
|
||||
|
||||
alias ppc_thread_state32_t = ppc_thread_state_t;
|
||||
|
||||
struct ppc_thread_state64_t
|
||||
{
|
||||
ulong srr0; /// Instruction address register (PC)
|
||||
ulong srr1; /// Machine state register (supervisor)
|
||||
ulong[32] r; /// General purpose register r0-r31
|
||||
uint cr; /// Condition register
|
||||
uint pad0;
|
||||
ulong xer; /// User's integer exception register
|
||||
ulong lr; /// Link register
|
||||
ulong ctr; /// Count register
|
||||
uint vrsave; /// Vector save register
|
||||
uint pad1;
|
||||
}
|
||||
|
||||
enum : mach_msg_type_number_t
|
||||
{
|
||||
PPC_THREAD_STATE_COUNT = cast(mach_msg_type_number_t) (ppc_thread_state_t.sizeof / uint.sizeof),
|
||||
PPC_THREAD_STATE32_COUNT = cast(mach_msg_type_number_t) (ppc_thread_state32_t.sizeof / uint.sizeof),
|
||||
PPC_THREAD_STATE64_COUNT = cast(mach_msg_type_number_t) (ppc_thread_state64_t.sizeof / uint.sizeof),
|
||||
}
|
||||
|
||||
alias MACHINE_THREAD_STATE = PPC_THREAD_STATE;
|
||||
alias MACHINE_THREAD_STATE_COUNT = PPC_THREAD_STATE_COUNT;
|
||||
|
||||
mach_port_t mach_thread_self();
|
||||
kern_return_t thread_suspend(thread_act_t);
|
||||
kern_return_t thread_resume(thread_act_t);
|
||||
kern_return_t thread_get_state(thread_act_t, thread_state_flavor_t, thread_state_t*, mach_msg_type_number_t*);
|
||||
}
|
||||
|
|
|
@ -63,3 +63,8 @@ private alias int function(dl_phdr_info*, size_t, void *) @nogc dl_iterate_phdr_
|
|||
|
||||
int dl_iterate_phdr(dl_iterate_phdr_cb __callback, void*__data);
|
||||
int dl_iterate_phdr(dl_iterate_phdr_cb_ngc __callback, void*__data) @nogc;
|
||||
|
||||
int _rtld_addr_phdr(const void*, dl_phdr_info*) @nogc
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -516,6 +516,46 @@ version (CRuntime_Glibc)
|
|||
int putc_unlocked(int, FILE*);
|
||||
int putchar_unlocked(int);
|
||||
}
|
||||
else version (CRuntime_Musl)
|
||||
{
|
||||
void flockfile(FILE*);
|
||||
int ftrylockfile(FILE*);
|
||||
void funlockfile(FILE*);
|
||||
int getc_unlocked(FILE*);
|
||||
int getchar_unlocked();
|
||||
int putc_unlocked(int, FILE*);
|
||||
int putchar_unlocked(int);
|
||||
}
|
||||
else version (Darwin)
|
||||
{
|
||||
void flockfile(FILE*);
|
||||
int ftrylockfile(FILE*);
|
||||
void funlockfile(FILE*);
|
||||
int getc_unlocked(FILE*);
|
||||
int getchar_unlocked();
|
||||
int putc_unlocked(int, FILE*);
|
||||
int putchar_unlocked(int);
|
||||
}
|
||||
else version (FreeBSD)
|
||||
{
|
||||
void flockfile(FILE*);
|
||||
int ftrylockfile(FILE*);
|
||||
void funlockfile(FILE*);
|
||||
int getc_unlocked(FILE*);
|
||||
int getchar_unlocked();
|
||||
int putc_unlocked(int, FILE*);
|
||||
int putchar_unlocked(int);
|
||||
}
|
||||
else version (NetBSD)
|
||||
{
|
||||
void flockfile(FILE*);
|
||||
int ftrylockfile(FILE*);
|
||||
void funlockfile(FILE*);
|
||||
int getc_unlocked(FILE*);
|
||||
int getchar_unlocked();
|
||||
int putc_unlocked(int, FILE*);
|
||||
int putchar_unlocked(int);
|
||||
}
|
||||
else version (OpenBSD)
|
||||
{
|
||||
void flockfile(FILE*);
|
||||
|
@ -526,6 +566,16 @@ else version (OpenBSD)
|
|||
int putc_unlocked(int, FILE*);
|
||||
int putchar_unlocked(int);
|
||||
}
|
||||
else version (DragonFlyBSD)
|
||||
{
|
||||
void flockfile(FILE*);
|
||||
int ftrylockfile(FILE*);
|
||||
void funlockfile(FILE*);
|
||||
int getc_unlocked(FILE*);
|
||||
int getchar_unlocked();
|
||||
int putc_unlocked(int, FILE*);
|
||||
int putchar_unlocked(int);
|
||||
}
|
||||
else version (Solaris)
|
||||
{
|
||||
void flockfile(FILE*);
|
||||
|
|
|
@ -57,12 +57,12 @@ alias COINIT_SPEED_OVER_MEMORY = COINIT.COINIT_SPEED_OVER_MEMORY;
|
|||
|
||||
public import core.sys.windows.uuid;
|
||||
|
||||
extern (System)
|
||||
extern (Windows)
|
||||
{
|
||||
|
||||
class ComObject : IUnknown
|
||||
{
|
||||
extern (System):
|
||||
extern (Windows):
|
||||
HRESULT QueryInterface(const(IID)* riid, void** ppv)
|
||||
{
|
||||
if (*riid == IID_IUnknown)
|
||||
|
|
|
@ -18,7 +18,7 @@ import core.sys.windows.windef;
|
|||
|
||||
public import core.sys.windows.dbghelp_types;
|
||||
|
||||
extern(System)
|
||||
extern(Windows)
|
||||
{
|
||||
alias BOOL function(HANDLE hProcess, DWORD64 lpBaseAddress, PVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead) ReadProcessMemoryProc64;
|
||||
alias PVOID function(HANDLE hProcess, DWORD64 AddrBase) FunctionTableAccessProc64;
|
||||
|
|
|
@ -414,7 +414,7 @@ int dll_getRefCount( HINSTANCE hInstance ) nothrow @nogc
|
|||
{
|
||||
version (GNU_InlineAsm)
|
||||
{
|
||||
asm pure nothrow @nogc { "movq %%gs:0x60, %0;" : "=r" peb; }
|
||||
asm pure nothrow @nogc { "movq %%gs:0x60, %0;" : "=r" (peb); }
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -431,7 +431,7 @@ int dll_getRefCount( HINSTANCE hInstance ) nothrow @nogc
|
|||
{
|
||||
version (GNU_InlineAsm)
|
||||
{
|
||||
asm pure nothrow @nogc { "movl %%fs:0x30, %0;" : "=r" peb; }
|
||||
asm pure nothrow @nogc { "movl %%fs:0x30, %0;" : "=r" (peb); }
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -172,7 +172,7 @@ struct thread_aux
|
|||
version (GNU_InlineAsm)
|
||||
{
|
||||
void** teb;
|
||||
asm pure nothrow @nogc { "movl %%fs:0x18, %0;" : "=r" teb; }
|
||||
asm pure nothrow @nogc { "movl %%fs:0x18, %0;" : "=r" (teb); }
|
||||
return teb;
|
||||
}
|
||||
else
|
||||
|
@ -190,7 +190,7 @@ struct thread_aux
|
|||
version (GNU_InlineAsm)
|
||||
{
|
||||
void** teb;
|
||||
asm pure nothrow @nogc { "movq %%gs:0x30, %0;" : "=r" teb; }
|
||||
asm pure nothrow @nogc { "movq %%gs:0x30, %0;" : "=r" (teb); }
|
||||
return teb;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -82,6 +82,8 @@ private
|
|||
|
||||
version (MinGW)
|
||||
version = GNU_AsmX86_Windows;
|
||||
else version (OSX)
|
||||
version = AsmX86_Posix;
|
||||
else version (Posix)
|
||||
version = AsmX86_Posix;
|
||||
}
|
||||
|
@ -105,13 +107,21 @@ private
|
|||
|
||||
version (MinGW)
|
||||
version = GNU_AsmX86_64_Windows;
|
||||
else version (OSX)
|
||||
version = AsmX86_64_Posix;
|
||||
else version (Posix)
|
||||
version = AsmX86_64_Posix;
|
||||
}
|
||||
}
|
||||
else version (PPC)
|
||||
{
|
||||
version (Posix)
|
||||
version (OSX)
|
||||
{
|
||||
version = AsmPPC_Darwin;
|
||||
version = AsmExternal;
|
||||
version = AlignFiberStackTo16Byte;
|
||||
}
|
||||
else version (Posix)
|
||||
{
|
||||
version = AsmPPC_Posix;
|
||||
version = AsmExternal;
|
||||
|
@ -119,7 +129,13 @@ private
|
|||
}
|
||||
else version (PPC64)
|
||||
{
|
||||
version (Posix)
|
||||
version (OSX)
|
||||
{
|
||||
version = AsmPPC_Darwin;
|
||||
version = AsmExternal;
|
||||
version = AlignFiberStackTo16Byte;
|
||||
}
|
||||
else version (Posix)
|
||||
{
|
||||
version = AlignFiberStackTo16Byte;
|
||||
}
|
||||
|
@ -1347,6 +1363,28 @@ private:
|
|||
|
||||
assert( (cast(size_t) pstack & 0x0f) == 0 );
|
||||
}
|
||||
else version (AsmPPC_Darwin)
|
||||
{
|
||||
version (StackGrowsDown) {}
|
||||
else static assert(false, "PowerPC Darwin only supports decrementing stacks");
|
||||
|
||||
uint wsize = size_t.sizeof;
|
||||
|
||||
// linkage + regs + FPRs + VRs
|
||||
uint space = 8 * wsize + 20 * wsize + 18 * 8 + 12 * 16;
|
||||
(cast(ubyte*)pstack - space)[0 .. space] = 0;
|
||||
|
||||
pstack -= wsize * 6;
|
||||
*cast(size_t*)pstack = cast(size_t) &fiber_entryPoint; // LR
|
||||
pstack -= wsize * 22;
|
||||
|
||||
// On Darwin PPC64 pthread self is in R13 (which is reserved).
|
||||
// At present, it is not safe to migrate fibers between threads, but if that
|
||||
// changes, then updating the value of R13 will also need to be handled.
|
||||
version (PPC64)
|
||||
*cast(size_t*)(pstack + wsize) = cast(size_t) Thread.getThis().m_addr;
|
||||
assert( (cast(size_t) pstack & 0x0f) == 0 );
|
||||
}
|
||||
else version (AsmMIPS_O32_Posix)
|
||||
{
|
||||
version (StackGrowsDown) {}
|
||||
|
|
|
@ -349,7 +349,8 @@ class Thread : ThreadBase
|
|||
}
|
||||
else version (Posix)
|
||||
{
|
||||
pthread_detach( m_addr );
|
||||
if (m_addr != m_addr.init)
|
||||
pthread_detach( m_addr );
|
||||
m_addr = m_addr.init;
|
||||
}
|
||||
version (Darwin)
|
||||
|
@ -420,6 +421,17 @@ class Thread : ThreadBase
|
|||
{
|
||||
uint[16] m_reg; // r0-r15
|
||||
}
|
||||
else version (PPC)
|
||||
{
|
||||
// Make the assumption that we only care about non-fp and non-vr regs.
|
||||
// ??? : it seems plausible that a valid address can be copied into a VR.
|
||||
uint[32] m_reg; // r0-31
|
||||
}
|
||||
else version (PPC64)
|
||||
{
|
||||
// As above.
|
||||
ulong[32] m_reg; // r0-31
|
||||
}
|
||||
else
|
||||
{
|
||||
static assert(false, "Architecture not supported." );
|
||||
|
@ -578,7 +590,7 @@ class Thread : ThreadBase
|
|||
{
|
||||
version (Windows)
|
||||
{
|
||||
if ( WaitForSingleObject( m_hndl, INFINITE ) != WAIT_OBJECT_0 )
|
||||
if ( m_addr != m_addr.init && WaitForSingleObject( m_hndl, INFINITE ) != WAIT_OBJECT_0 )
|
||||
throw new ThreadException( "Unable to join thread" );
|
||||
// NOTE: m_addr must be cleared before m_hndl is closed to avoid
|
||||
// a race condition with isRunning. The operation is done
|
||||
|
@ -589,7 +601,7 @@ class Thread : ThreadBase
|
|||
}
|
||||
else version (Posix)
|
||||
{
|
||||
if ( pthread_join( m_addr, null ) != 0 )
|
||||
if ( m_addr != m_addr.init && pthread_join( m_addr, null ) != 0 )
|
||||
throw new ThreadException( "Unable to join thread" );
|
||||
// NOTE: pthread_join acts as a substitute for pthread_detach,
|
||||
// which is normally called by the dtor. Setting m_addr
|
||||
|
@ -1629,9 +1641,9 @@ package extern(D) void* getStackBottom() nothrow @nogc
|
|||
void *bottom;
|
||||
|
||||
version (X86)
|
||||
asm pure nothrow @nogc { "movl %%fs:4, %0;" : "=r" bottom; }
|
||||
asm pure nothrow @nogc { "movl %%fs:4, %0;" : "=r" (bottom); }
|
||||
else version (X86_64)
|
||||
asm pure nothrow @nogc { "movq %%gs:8, %0;" : "=r" bottom; }
|
||||
asm pure nothrow @nogc { "movq %%gs:8, %0;" : "=r" (bottom); }
|
||||
else
|
||||
static assert(false, "Platform not supported.");
|
||||
|
||||
|
@ -1880,6 +1892,28 @@ private extern (D) bool suspend( Thread t ) nothrow @nogc
|
|||
t.m_reg[14] = state.lr;
|
||||
t.m_reg[15] = state.pc;
|
||||
}
|
||||
else version (PPC)
|
||||
{
|
||||
ppc_thread_state_t state = void;
|
||||
mach_msg_type_number_t count = PPC_THREAD_STATE_COUNT;
|
||||
|
||||
if (thread_get_state(t.m_tmach, PPC_THREAD_STATE, &state, &count) != KERN_SUCCESS)
|
||||
onThreadError("Unable to load thread state");
|
||||
if (!t.m_lock)
|
||||
t.m_curr.tstack = cast(void*) state.r[1];
|
||||
t.m_reg[] = state.r[];
|
||||
}
|
||||
else version (PPC64)
|
||||
{
|
||||
ppc_thread_state64_t state = void;
|
||||
mach_msg_type_number_t count = PPC_THREAD_STATE64_COUNT;
|
||||
|
||||
if (thread_get_state(t.m_tmach, PPC_THREAD_STATE64, &state, &count) != KERN_SUCCESS)
|
||||
onThreadError("Unable to load thread state");
|
||||
if (!t.m_lock)
|
||||
t.m_curr.tstack = cast(void*) state.r[1];
|
||||
t.m_reg[] = state.r[];
|
||||
}
|
||||
else
|
||||
{
|
||||
static assert(false, "Architecture not supported." );
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
* Source: $(DRUNTIMESRC core/thread/osthread.d)
|
||||
*/
|
||||
|
||||
/* NOTE: This file has been patched from the original DMD distribution to
|
||||
* work with the GDC compiler.
|
||||
*/
|
||||
module core.thread.threadbase;
|
||||
|
||||
import core.thread.context;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
f89dc217a680fa1a83f2999fea04b7c562f705ee
|
||||
e6907ff3e28d3c43469c46df4a0426726ecb8631
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
merge done from the dlang/phobos repository.
|
||||
|
|
|
@ -1358,7 +1358,8 @@ version (Windows)
|
|||
|
||||
|
||||
/**
|
||||
Flags that control the behaviour of $(LREF spawnProcess) and
|
||||
Flags that control the behaviour of process creation functions in this
|
||||
module. Most flags only apply to $(LREF spawnProcess) and
|
||||
$(LREF spawnShell).
|
||||
|
||||
Use bitwise OR to combine flags.
|
||||
|
@ -1433,6 +1434,21 @@ enum Config
|
|||
Calling $(LREF wait) or $(LREF kill) with the resulting $(D Pid) is invalid.
|
||||
*/
|
||||
detached = 64,
|
||||
|
||||
/**
|
||||
By default, the $(LREF execute) and $(LREF executeShell) functions
|
||||
will capture child processes' both stdout and stderr. This can be
|
||||
undesirable if the standard output is to be processed or otherwise
|
||||
used by the invoking program, as `execute`'s result would then
|
||||
contain a mix of output and warning/error messages.
|
||||
|
||||
Specify this flag when calling `execute` or `executeShell` to
|
||||
cause invoked processes' stderr stream to be sent to $(REF stderr,
|
||||
std,stdio), and only capture and return standard output.
|
||||
|
||||
This flag has no effect on $(LREF spawnProcess) or $(LREF spawnShell).
|
||||
*/
|
||||
stderrPassThrough = 128,
|
||||
}
|
||||
|
||||
|
||||
|
@ -2487,7 +2503,11 @@ private auto executeImpl(alias pipeFunc, Cmd, ExtraPipeFuncArgs...)(
|
|||
import std.array : appender;
|
||||
import std.typecons : Tuple;
|
||||
|
||||
auto p = pipeFunc(commandLine, Redirect.stdout | Redirect.stderrToStdout,
|
||||
auto redirect = (config & Config.stderrPassThrough)
|
||||
? Redirect.stdout
|
||||
: Redirect.stdout | Redirect.stderrToStdout;
|
||||
|
||||
auto p = pipeFunc(commandLine, redirect,
|
||||
env, config, workDir, extraArgs);
|
||||
|
||||
auto a = appender!(ubyte[])();
|
||||
|
@ -2551,6 +2571,30 @@ private auto executeImpl(alias pipeFunc, Cmd, ExtraPipeFuncArgs...)(
|
|||
assert(r3.output.empty);
|
||||
}
|
||||
|
||||
@system unittest
|
||||
{
|
||||
// Temporarily disable output to stderr so as to not spam the build log.
|
||||
import std.stdio : stderr;
|
||||
import std.typecons : Tuple;
|
||||
import std.file : readText;
|
||||
import std.traits : ReturnType;
|
||||
|
||||
ReturnType!executeShell r;
|
||||
auto tmpname = uniqueTempPath;
|
||||
auto t = stderr;
|
||||
// Open a new scope to minimize code ran with stderr redirected.
|
||||
{
|
||||
stderr.open(tmpname, "w");
|
||||
scope(exit) stderr = t;
|
||||
r = executeShell("echo D rox>&2", null, Config.stderrPassThrough);
|
||||
}
|
||||
assert(r.status == 0);
|
||||
assert(r.output.empty);
|
||||
auto witness = readText(tmpname);
|
||||
import std.ascii : newline;
|
||||
assert(witness == "D rox" ~ newline, "'" ~ witness ~ "'");
|
||||
}
|
||||
|
||||
@safe unittest
|
||||
{
|
||||
import std.typecons : Tuple;
|
||||
|
@ -2750,8 +2794,7 @@ private struct TestScript
|
|||
string path;
|
||||
}
|
||||
|
||||
version (unittest)
|
||||
private string uniqueTempPath() @safe
|
||||
package(std) string uniqueTempPath() @safe
|
||||
{
|
||||
import std.file : tempDir;
|
||||
import std.path : buildPath;
|
||||
|
|
Loading…
Add table
Reference in a new issue