-1134b71039881464e9bf021836d82796b3a1fcfc
+89f870b76710a4cfa96f711bb5b14a7439c5c2a7
The first line of this file holds the git revision number of the last
merge done from the dlang/druntime repository.
}
}
-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
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.");
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;
pure int _fpclass(double x);
}
+ version (MinGW)
+ {
enum
{
///
- FP_SUBNORMAL = -2,
+ FP_NAN = 0x0100,
///
- FP_NORMAL = -1,
+ FP_NORMAL = 0x0400,
///
- FP_ZERO = 0,
+ FP_INFINITE = FP_NAN | FP_NORMAL,
///
- FP_INFINITE = 1,
+ FP_ZERO = 0x0400,
///
- FP_NAN = 2,
+ FP_SUBNORMAL = FP_NORMAL | FP_ZERO
}
- 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)
- {
- static if (real.sizeof == double.sizeof)
- return fpclassify(cast(double) x);
- else
- static assert(false, "fpclassify(real) not supported by MS C runtime");
- }
+ pure int __fpclassifyf(float x);
+ pure int __fpclassify(double x);
+ pure int __fpclassifyl(real x);
- //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; }
+ pure int __isnanf(float x);
+ pure int __isnan(double x);
+ pure int __isnanl(real x);
- //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; }
+ pure int __signbitf(float x);
+ pure int __signbit(double x);
+ pure int __signbitl(real x);
- //int isnan(real-floating x);
- version (none) // requires MSVCRT 12+ (VS 2013)
+ 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 isnan(float x) { return fpclassify(x) == FP_NAN; }
+ pure int isfinite(double x) { return (fpclassify(x) & FP_NORMAL) == 0; }
///
- pure int isnan(double x) { return fpclassify(x) == FP_NAN; }
+ 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);
///
- pure int isnan(real x) { return fpclassify(x) == FP_NAN; }
+ 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 // for backward compatibility with older runtimes
+ }
+ else
+ {
+ enum
{
///
- pure int isnan(float x) { version (Win64) return _isnanf(x); else return _isnan(cast(double) x); }
+ FP_SUBNORMAL = -2,
+ ///
+ FP_NORMAL = -1,
///
- extern(C) pragma(mangle, "_isnan") pure int isnan(double x);
+ FP_ZERO = 0,
///
- pure int isnan(real x) { return _isnan(cast(double) x); }
+ FP_INFINITE = 1,
+ ///
+ FP_NAN = 2,
}
- //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)
+ extern(D)
{
- static if (real.sizeof == double.sizeof)
- return signbit(cast(double) x);
- else
- return (cast(short*)&(x))[4] & 0x8000;
+ //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 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 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 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
FP_FAST_FMAL = 1,
}
- pure int __fpclassifyd(double);
+ pure int __fpclassify(double);
pure int __fpclassifyf(float);
pure int __fpclassifyl(real);
pure int __isfinitef(float);
///
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);
///
pure int fileno()(FILE* stream) { return stream._file; }
}
- ///
+ ///
pragma(printf)
int _snprintf(scope char* s, size_t n, scope const char* fmt, scope const ...);
///
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)
{
int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
}
+ //
+ // 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 _fputc_nolock(int c, FILE *fp);
+ int _fputc_nolock(int c, _iobuf* fp);
///
- int _fgetc_nolock(FILE *fp);
-
+ int _fgetc_nolock(_iobuf* fp);
///
- int _lock_file(FILE *fp);
+ wint_t _fputwc_nolock(wchar_t c, _iobuf* fp);
///
- int _unlock_file(FILE *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);
///
///
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)
{
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
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
{
alias core.stdc.math.fabs fabs;
version (CRuntime_Microsoft)
{
+ version (MinGW)
+ {
+ ///
+ alias core.stdc.math.fabsf fabs;
+ ///
+ alias core.stdc.math.fabsl fabs;
+ }
}
else
{
version = AnyARM;
version (ARM)
version = AnyARM;
+version (PPC)
+ version = AnyPPC;
+version (PPC64)
+ version = AnyPPC;
version (i386)
{
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*);
+}
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;
+}
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*);
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*);
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)
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;
{
version (GNU_InlineAsm)
{
- asm pure nothrow @nogc { "movq %%gs:0x60, %0;" : "=r" peb; }
+ asm pure nothrow @nogc { "movq %%gs:0x60, %0;" : "=r" (peb); }
}
else
{
{
version (GNU_InlineAsm)
{
- asm pure nothrow @nogc { "movl %%fs:0x30, %0;" : "=r" peb; }
+ asm pure nothrow @nogc { "movl %%fs:0x30, %0;" : "=r" (peb); }
}
else
{
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
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
version (MinGW)
version = GNU_AsmX86_Windows;
+ else version (OSX)
+ version = AsmX86_Posix;
else version (Posix)
version = AsmX86_Posix;
}
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;
}
else version (PPC64)
{
- version (Posix)
+ version (OSX)
+ {
+ version = AsmPPC_Darwin;
+ version = AsmExternal;
+ version = AlignFiberStackTo16Byte;
+ }
+ else version (Posix)
{
version = AlignFiberStackTo16Byte;
}
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) {}
}
else version (Posix)
{
- pthread_detach( m_addr );
+ if (m_addr != m_addr.init)
+ pthread_detach( m_addr );
m_addr = m_addr.init;
}
version (Darwin)
{
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." );
{
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
}
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
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.");
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." );
* 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;
-f89dc217a680fa1a83f2999fea04b7c562f705ee
+e6907ff3e28d3c43469c46df4a0426726ecb8631
The first line of this file holds the git revision number of the last
merge done from the dlang/phobos repository.
/**
-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.
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,
}
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[])();
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;
string path;
}
-version (unittest)
-private string uniqueTempPath() @safe
+package(std) string uniqueTempPath() @safe
{
import std.file : tempDir;
import std.path : buildPath;