From patchwork Mon Apr 19 17:32:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Buclaw X-Patchwork-Id: 1468018 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=SMRoEANE; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4FPDRz3FmBz9vFD for ; Tue, 20 Apr 2021 03:33:17 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 882253952535; Mon, 19 Apr 2021 17:33:14 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 882253952535 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1618853594; bh=WPAsJ9pbMSiX77bZbZsHrQZ1/iGbexagTGO2ksBeIY4=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=SMRoEANEoqysRTnDijqZz6/kktVrQmSBOAzcEa2qnAy/tk4tK2nMVWdzpEAzVJ7g1 hj+51AWFoc66JrX73smLUWEPzHeTPNRRL+8Yu8DVtDk/akLr2LBvaqIjaSODS90Xdo V3QOhhM3S5iZO7Q1R/8TSYEH9cJ8pVHQaJtzYgWM= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mout-p-201.mailbox.org (mout-p-201.mailbox.org [80.241.56.171]) by sourceware.org (Postfix) with ESMTPS id 2EC5E385701F for ; Mon, 19 Apr 2021 17:33:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 2EC5E385701F Received: from smtp1.mailbox.org (smtp1.mailbox.org [IPv6:2001:67c:2050:105:465:1:1:0]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-201.mailbox.org (Postfix) with ESMTPS id 4FPDRf2g3fzQjxC; Mon, 19 Apr 2021 19:33:02 +0200 (CEST) X-Virus-Scanned: amavisd-new at heinlein-support.de Received: from smtp1.mailbox.org ([80.241.60.240]) by spamfilter03.heinlein-hosting.de (spamfilter03.heinlein-hosting.de [80.241.56.117]) (amavisd-new, port 10030) with ESMTP id dk_a2BYyAK9B; Mon, 19 Apr 2021 19:32:56 +0200 (CEST) To: gcc-patches@gcc.gnu.org Subject: [committed] libphobos: Merge upstream druntime 89f870b7, phobos e6907ff3e Date: Mon, 19 Apr 2021 19:32:51 +0200 Message-Id: <20210419173251.3760235-1-ibuclaw@gdcproject.org> MIME-Version: 1.0 X-MBO-SPAM-Probability: X-Rspamd-Score: -0.29 / 15.00 / 15.00 X-Rspamd-Queue-Id: 175BD186F X-Rspamd-UID: 8c9a7a X-Spam-Status: No, score=-15.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Iain Buclaw via Gcc-patches From: Iain Buclaw Reply-To: Iain Buclaw Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" Hi, This patch merges the D runtime library with upstream druntime 89f870b7, and phobos e6907ff3e. Synchronizes the C bindings with the latest port fixes in upstream druntime, and adds a Config.stderrPassThrough enum member to std.process (fixing PR98494). Bootstrapped and regression tested on x86_64-linux-gnu/-m32/-mx32, and committed to mainline. --- libphobos/ChangeLog: PR d/98494 * libdruntime/MERGE: Merge upstream druntime 89f870b7. * src/MERGE: Merge upstream phobos e6907ff3e. --- libphobos/libdruntime/MERGE | 2 +- libphobos/libdruntime/core/stdc/config.d | 39 +-- libphobos/libdruntime/core/stdc/math.d | 295 +++++++++--------- libphobos/libdruntime/core/stdc/stdio.d | 82 ++++- libphobos/libdruntime/core/stdc/stdlib.d | 27 +- libphobos/libdruntime/core/stdc/tgmath.d | 7 + .../core/sys/darwin/mach/thread_act.d | 66 ++++ .../core/sys/openbsd/sys/link_elf.d | 5 + libphobos/libdruntime/core/sys/posix/stdio.d | 50 +++ libphobos/libdruntime/core/sys/windows/com.d | 4 +- .../libdruntime/core/sys/windows/dbghelp.d | 2 +- libphobos/libdruntime/core/sys/windows/dll.d | 4 +- .../libdruntime/core/sys/windows/threadaux.d | 4 +- libphobos/libdruntime/core/thread/fiber.d | 42 ++- libphobos/libdruntime/core/thread/osthread.d | 44 ++- .../libdruntime/core/thread/threadbase.d | 3 + libphobos/src/MERGE | 2 +- libphobos/src/std/process.d | 51 ++- 18 files changed, 520 insertions(+), 209 deletions(-) diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index d839a08c19b..25cbb955ba2 100644 --- a/libphobos/libdruntime/MERGE +++ b/libphobos/libdruntime/MERGE @@ -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. diff --git a/libphobos/libdruntime/core/stdc/config.d b/libphobos/libdruntime/core/stdc/config.d index 802f5b6fb21..44bb7077b59 100644 --- a/libphobos/libdruntime/core/stdc/config.d +++ b/libphobos/libdruntime/core/stdc/config.d @@ -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; diff --git a/libphobos/libdruntime/core/stdc/math.d b/libphobos/libdruntime/core/stdc/math.d index fba78ee233a..2de6e579575 100644 --- a/libphobos/libdruntime/core/stdc/math.d +++ b/libphobos/libdruntime/core/stdc/math.d @@ -424,92 +424,177 @@ else version (CRuntime_Microsoft) // fully supported since MSVCRT 12 (VS 2013) o 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; + } } } } @@ -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); diff --git a/libphobos/libdruntime/core/stdc/stdio.d b/libphobos/libdruntime/core/stdc/stdio.d index 532a0803f55..c76b922a3eb 100644 --- a/libphobos/libdruntime/core/stdc/stdio.d +++ b/libphobos/libdruntime/core/stdc/stdio.d @@ -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); } + // + // 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); /// @@ -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 diff --git a/libphobos/libdruntime/core/stdc/stdlib.d b/libphobos/libdruntime/core/stdc/stdlib.d index 5d69b880bc8..35e81a25414 100644 --- a/libphobos/libdruntime/core/stdc/stdlib.d +++ b/libphobos/libdruntime/core/stdc/stdlib.d @@ -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 { diff --git a/libphobos/libdruntime/core/stdc/tgmath.d b/libphobos/libdruntime/core/stdc/tgmath.d index 2ff1522fd81..2d1a198543f 100644 --- a/libphobos/libdruntime/core/stdc/tgmath.d +++ b/libphobos/libdruntime/core/stdc/tgmath.d @@ -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 { diff --git a/libphobos/libdruntime/core/sys/darwin/mach/thread_act.d b/libphobos/libdruntime/core/sys/darwin/mach/thread_act.d index b61673fb4f1..d455d1b8303 100644 --- a/libphobos/libdruntime/core/sys/darwin/mach/thread_act.d +++ b/libphobos/libdruntime/core/sys/darwin/mach/thread_act.d @@ -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*); +} diff --git a/libphobos/libdruntime/core/sys/openbsd/sys/link_elf.d b/libphobos/libdruntime/core/sys/openbsd/sys/link_elf.d index f88671a3160..55fc79268e2 100644 --- a/libphobos/libdruntime/core/sys/openbsd/sys/link_elf.d +++ b/libphobos/libdruntime/core/sys/openbsd/sys/link_elf.d @@ -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; +} diff --git a/libphobos/libdruntime/core/sys/posix/stdio.d b/libphobos/libdruntime/core/sys/posix/stdio.d index 031bcb7341f..41b52da7c64 100644 --- a/libphobos/libdruntime/core/sys/posix/stdio.d +++ b/libphobos/libdruntime/core/sys/posix/stdio.d @@ -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*); diff --git a/libphobos/libdruntime/core/sys/windows/com.d b/libphobos/libdruntime/core/sys/windows/com.d index 88007adb141..6935dd94f95 100644 --- a/libphobos/libdruntime/core/sys/windows/com.d +++ b/libphobos/libdruntime/core/sys/windows/com.d @@ -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) diff --git a/libphobos/libdruntime/core/sys/windows/dbghelp.d b/libphobos/libdruntime/core/sys/windows/dbghelp.d index 8c9827034e9..9848fb99115 100644 --- a/libphobos/libdruntime/core/sys/windows/dbghelp.d +++ b/libphobos/libdruntime/core/sys/windows/dbghelp.d @@ -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; diff --git a/libphobos/libdruntime/core/sys/windows/dll.d b/libphobos/libdruntime/core/sys/windows/dll.d index 3df0d7fd41b..cc2422bcaa0 100644 --- a/libphobos/libdruntime/core/sys/windows/dll.d +++ b/libphobos/libdruntime/core/sys/windows/dll.d @@ -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 { diff --git a/libphobos/libdruntime/core/sys/windows/threadaux.d b/libphobos/libdruntime/core/sys/windows/threadaux.d index fb4d1ee64ba..34fda656c8c 100644 --- a/libphobos/libdruntime/core/sys/windows/threadaux.d +++ b/libphobos/libdruntime/core/sys/windows/threadaux.d @@ -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 diff --git a/libphobos/libdruntime/core/thread/fiber.d b/libphobos/libdruntime/core/thread/fiber.d index 67d9937e31a..f4c04ce7358 100644 --- a/libphobos/libdruntime/core/thread/fiber.d +++ b/libphobos/libdruntime/core/thread/fiber.d @@ -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) {} diff --git a/libphobos/libdruntime/core/thread/osthread.d b/libphobos/libdruntime/core/thread/osthread.d index 0fffc7ed3f7..31764e69691 100644 --- a/libphobos/libdruntime/core/thread/osthread.d +++ b/libphobos/libdruntime/core/thread/osthread.d @@ -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." ); diff --git a/libphobos/libdruntime/core/thread/threadbase.d b/libphobos/libdruntime/core/thread/threadbase.d index 50795e444be..0a8de10e17b 100644 --- a/libphobos/libdruntime/core/thread/threadbase.d +++ b/libphobos/libdruntime/core/thread/threadbase.d @@ -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; diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE index 4f6a168350b..6f9740404ef 100644 --- a/libphobos/src/MERGE +++ b/libphobos/src/MERGE @@ -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. diff --git a/libphobos/src/std/process.d b/libphobos/src/std/process.d index b0310a870d9..9cbeca8e9a8 100644 --- a/libphobos/src/std/process.d +++ b/libphobos/src/std/process.d @@ -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;