libphobos: Merge upstream druntime 5cc061a8, phobos 64ed4684f
authorIain Buclaw <ibuclaw@gdcproject.org>
Sun, 17 May 2020 16:49:19 +0000 (18:49 +0200)
committerIain Buclaw <ibuclaw@gdcproject.org>
Sun, 17 May 2020 16:49:19 +0000 (18:49 +0200)
- core.cpuid has been fixed to not use i7 detection on AMD processors.
- std.net.curl has been fixed to correctly handle HTTP/2 status lines.
- std.zip has had a test fixed to not rely on unzip being installed.

Fixes: PR d/95166
       PR d/95167
       PR d/95168

Reviewed-on: https://github.com/dlang/druntime/pull/3107
     https://github.com/dlang/phobos/pull/7486

libphobos/libdruntime/MERGE
libphobos/libdruntime/core/cpuid.d
libphobos/src/MERGE
libphobos/src/std/net/curl.d
libphobos/src/std/zip.d

index c61ad7ca7ed020756ffffc0458fc9f39349bba56..5e3bf3b795a99b92c38e9576e402fd83c2676d71 100644 (file)
@@ -1,4 +1,4 @@
-7bdd83d7b4bd9fd4cb9ffca0d50babc90b31bfd6
+5cc061a8733731d5b40334c0eb7a927b6d6241ce
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/druntime repository.
index 839605aee1e61774c64ea13650fb1c9151f9ac43..2ba13b55bf1bb828058f709f3bea99aaa5f93d7e 100644 (file)
@@ -941,13 +941,27 @@ void cpuidX86()
             datacache[0].lineSize = 32;
         }
     }
-    if (max_cpuid >= 0x0B) {
+    if (cf.probablyIntel && max_cpuid >= 0x0B) {
         // For Intel i7 and later, use function 0x0B to determine
         // cores and hyperthreads.
         getCpuInfo0B();
     } else {
         if (hyperThreadingBit) cf.maxThreads = (apic>>>16) & 0xFF;
         else cf.maxThreads = cf.maxCores;
+
+        if (cf.probablyAMD && max_extended_cpuid >= 0x8000_001E) {
+            version (GNU) asm pure nothrow @nogc {
+                "cpuid" : "=a" (a), "=b" (b) : "a" (0x8000_001E) : "ecx", "edx";
+            } else {
+                asm pure nothrow @nogc {
+                    mov EAX, 0x8000_001e;
+                    cpuid;
+                    mov b, EBX;
+                }
+            }
+            ubyte coresPerComputeUnit = ((b >> 8) & 3) + 1;
+            cf.maxCores = cf.maxThreads / coresPerComputeUnit;
+        }
     }
 }
 
@@ -975,7 +989,7 @@ bool hasCPUID()
                 xor {(%%esp), %%eax|eax, [esp]}
                                            # eax = whichever bits were changed
                 popf{l|d}                  # Restore original EFLAGS
-                " : "=a" flags;
+                " : "=a" (flags);
             }
         }
         else version (D_InlineAsm_X86)
index 6025cdcc1f736d26adde2261e54b30a78357a2c1..5900ca7c6a4394ab33832d5b9b5e3476c1463f9c 100644 (file)
@@ -1,4 +1,4 @@
-bf0d0a37c4c2d8762ceff7d8677e7584b770800f
+64ed4684fa2a0f2401f5b6df34f6dcb4c3973945
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/phobos repository.
index 32ba45ce2de7c222265af63614d70f98483f988c..445f996ea08c1c3a7a096025862a8b2a7d32c4aa 100644 (file)
@@ -2451,7 +2451,6 @@ struct HTTP
                                                      in char[] value) callback)
         {
             import std.algorithm.searching : startsWith;
-            import std.conv : to;
             import std.regex : regex, match;
             import std.uni : toLower;
 
@@ -2471,18 +2470,8 @@ struct HTTP
                     if (header.startsWith("HTTP/"))
                     {
                         headersIn.clear();
-
-                        const m = match(header, regex(r"^HTTP/(\d+)\.(\d+) (\d+) (.*)$"));
-                        if (m.empty)
+                        if (parseStatusLine(header, status))
                         {
-                            // Invalid status line
-                        }
-                        else
-                        {
-                            status.majorVersion = to!ushort(m.captures[1]);
-                            status.minorVersion = to!ushort(m.captures[2]);
-                            status.code = to!ushort(m.captures[3]);
-                            status.reason = m.captures[4].idup;
                             if (onReceiveStatusLine != null)
                                 onReceiveStatusLine(status);
                         }
@@ -2517,6 +2506,37 @@ struct HTTP
 
     private RefCounted!Impl p;
 
+    /// Parse status line, as received from / generated by cURL.
+    private static bool parseStatusLine(in char[] header, out StatusLine status) @safe
+    {
+        import std.conv : to;
+        import std.regex : regex, match;
+
+        const m = match(header, regex(r"^HTTP/(\d+)(?:\.(\d+))? (\d+)(?: (.*))?$"));
+        if (m.empty)
+            return false; // Invalid status line
+        else
+        {
+            status.majorVersion = to!ushort(m.captures[1]);
+            status.minorVersion = m.captures[2].length ? to!ushort(m.captures[2]) : 0;
+            status.code = to!ushort(m.captures[3]);
+            status.reason = m.captures[4].idup;
+            return true;
+        }
+    }
+
+    @safe unittest
+    {
+        StatusLine status;
+        assert(parseStatusLine("HTTP/1.1 200 OK", status)
+            && status == StatusLine(1, 1, 200, "OK"));
+        assert(parseStatusLine("HTTP/1.0 304 Not Modified", status)
+            && status == StatusLine(1, 0, 304, "Not Modified"));
+        // The HTTP2 protocol is binary; cURL generates this fake text header.
+        assert(parseStatusLine("HTTP/2 200", status)
+            && status == StatusLine(2, 0, 200, null));
+    }
+
     /** Time condition enumeration as an alias of $(REF CurlTimeCond, etc,c,curl)
 
         $(HTTP www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.25, _RFC2616 Section 14.25)
index db47ddef0c9cc539825afd1ee64c70af550e3698..8b130ea2dd9ce123063ed7ef1da12b11caf161d5 100644 (file)
@@ -970,6 +970,12 @@ version (Posix) @system unittest
 {
     import std.datetime, std.file, std.format, std.path, std.process, std.stdio;
 
+    if (executeShell("unzip").status != 0)
+    {
+        writeln("Can't run unzip, skipping unzip test");
+        return;
+    }
+
     auto zr = new ZipArchive();
     auto am = new ArchiveMember();
     am.compressionMethod = CompressionMethod.deflate;