Alexandre Goujon : msvcrt: Implement 64-bit version of __std_type_info_hash.

Alexandre Julliard julliard at winehq.org
Thu Oct 6 14:46:54 CDT 2016


Module: wine
Branch: master
Commit: eac56fbda547e21cf9f40d57c913b3b582fc5697
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=eac56fbda547e21cf9f40d57c913b3b582fc5697

Author: Alexandre Goujon <ale.goujon at gmail.com>
Date:   Wed Oct  5 20:51:52 2016 +0200

msvcrt: Implement 64-bit version of __std_type_info_hash.

Signed-off-by: GOUJON Alexandre <ale.goujon at gmail.com>
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msvcrt/cpp.c         | 19 +++++++++++++++----
 dlls/ucrtbase/tests/cpp.c | 11 +++++++----
 2 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/dlls/msvcrt/cpp.c b/dlls/msvcrt/cpp.c
index 0ffe61e..f7127a3 100644
--- a/dlls/msvcrt/cpp.c
+++ b/dlls/msvcrt/cpp.c
@@ -1591,20 +1591,31 @@ void CDECL MSVCRT_type_info_destroy_list(SLIST_HEADER *header)
 
 /******************************************************************
  *              __std_type_info_hash (UCRTBASE.@)
- *
- * TODO: 64-bit version of the function uses different constants
  */
 MSVCRT_size_t CDECL MSVCRT_type_info_hash(const type_info140 *ti)
 {
-    MSVCRT_size_t hash = 0x811c9dc5;
+    MSVCRT_size_t hash, fnv_prime;
     const char *p;
 
+#ifdef _WIN64
+    hash = 0xcbf29ce484222325;
+    fnv_prime = 0x100000001b3;
+#else
+    hash = 0x811c9dc5;
+    fnv_prime = 0x1000193;
+#endif
+
     TRACE("(%p)->%s\n", ti, ti->mangled);
 
     for(p = ti->mangled+1; *p; p++) {
         hash ^= *p;
-        hash *= 0x1000193;
+        hash *= fnv_prime;
     }
+
+#ifdef _WIN64
+    hash ^= hash >> 32;
+#endif
+
     return hash;
 }
 #endif
diff --git a/dlls/ucrtbase/tests/cpp.c b/dlls/ucrtbase/tests/cpp.c
index 1a01fea..163e196 100644
--- a/dlls/ucrtbase/tests/cpp.c
+++ b/dlls/ucrtbase/tests/cpp.c
@@ -163,19 +163,22 @@ static void test___std_type_info(void)
     ti1.mangled[2] = 0;
     hash1 = p___std_type_info_hash(&ti1);
 #ifdef _WIN64
-    todo_wine ok(hash1 == 0xcbf29ce44fd0bfc1, "hash = %p\n", (void*)hash1);
+    ok(hash1 == 0xcbf29ce44fd0bfc1, "hash = %p\n", (void*)hash1);
 #else
     ok(hash1 == 0x811c9dc5, "hash = %p\n", (void*)hash1);
 #endif
 
     ti1.mangled[0] = 1;
     hash2 = p___std_type_info_hash(&ti1);
-    ok(hash1 == hash2, "hash1 != hash2 (first char not ignorred)\n");
+    ok(hash1 == hash2, "hash1 != hash2 (first char not ignored)\n");
 
     ti1.mangled[1] = 1;
     hash1 = p___std_type_info_hash(&ti1);
-    if(sizeof(void*) == sizeof(int))
-        ok(hash1 == 0x40c5b8c, "hash = %p\n", (void*)hash1);
+#ifdef _WIN64
+    ok(hash1 == 0xaf63bc4c29620a60, "hash = %p\n", (void*)hash1);
+#else
+    ok(hash1 == 0x40c5b8c, "hash = %p\n", (void*)hash1);
+#endif
     ok(hash1 != hash2, "hash1 == hash2 for different strings\n");
 
     ti1.mangled[1] = 2;




More information about the wine-cvs mailing list