Unify Number to StringImpl conversion
authorbenjamin@webkit.org <benjamin@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 25 Aug 2012 00:13:19 +0000 (00:13 +0000)
committerbenjamin@webkit.org <benjamin@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 25 Aug 2012 00:13:19 +0000 (00:13 +0000)
https://bugs.webkit.org/show_bug.cgi?id=94879

Patch by Benjamin Poulain <bpoulain@apple.com> on 2012-08-24
Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
* runtime/UString.cpp:
* runtime/UString.h:
(JSC::UString::number):
Update UString to directly use the common NumberToString implementation.

Source/WebKit2:

* win/WebKit2.def: Update the exported symbols.

Source/WTF:

Previously, UString::number() and String::number() used different implementations.

WTF::String::number() was simply forwarding to String::format().
UString::number() had an optimized version of the conversion.

This patch replace both implementation by a new version, faster than the two previous versions.

The new functions numberToStringImpl improvements are:
-about 3 times faster than String::number().
-14% faster than UString::number() on signed numbers.
-9% faster than UString::number() on unsigned numbers.

* GNUmakefile.list.am:
* WTF.gypi:
* WTF.pro:
* WTF.vcproj/WTF.vcproj:
* WTF.xcodeproj/project.pbxproj:
* wtf/CMakeLists.txt:
* wtf/text/IntegerToStringConversion.cpp: Added.
(WTF::numberToStringImplSigned):
(WTF::numberToStringImpl):
(WTF::numberToStringImplUnsigned):
* wtf/text/IntegerToStringConversion.h: Added.
* wtf/text/WTFString.cpp:
(WTF::String::format):
* wtf/text/WTFString.h:
(WTF::String::number):

Tools:

Add testing for the new IntegerToStringConversion.

* TestWebKitAPI/CMakeLists.txt:
* TestWebKitAPI/GNUmakefile.am:
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WTF/IntegerToStringConversion.cpp: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@126658 268f45cc-cd09-0410-ab3c-d52691b4dbfc

22 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
Source/JavaScriptCore/runtime/UString.cpp
Source/JavaScriptCore/runtime/UString.h
Source/WTF/ChangeLog
Source/WTF/GNUmakefile.list.am
Source/WTF/WTF.gypi
Source/WTF/WTF.pro
Source/WTF/WTF.vcproj/WTF.vcproj
Source/WTF/WTF.xcodeproj/project.pbxproj
Source/WTF/wtf/CMakeLists.txt
Source/WTF/wtf/text/IntegerToStringConversion.cpp [new file with mode: 0644]
Source/WTF/wtf/text/IntegerToStringConversion.h [new file with mode: 0644]
Source/WTF/wtf/text/WTFString.cpp
Source/WTF/wtf/text/WTFString.h
Source/WebKit2/ChangeLog
Source/WebKit2/win/WebKit2.def
Tools/ChangeLog
Tools/TestWebKitAPI/CMakeLists.txt
Tools/TestWebKitAPI/GNUmakefile.am
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WTF/IntegerToStringConversion.cpp [new file with mode: 0644]

index 21a2b86eed64e3798e46ea52b3ae943d69d20fac..6ba4f539cbe973868d6c3f73f609b98a20a2d30e 100644 (file)
@@ -1,3 +1,16 @@
+2012-08-24  Benjamin Poulain  <bpoulain@apple.com>
+
+        Unify Number to StringImpl conversion
+        https://bugs.webkit.org/show_bug.cgi?id=94879
+
+        Reviewed by Geoffrey Garen.
+
+        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+        * runtime/UString.cpp:
+        * runtime/UString.h:
+        (JSC::UString::number):
+        Update UString to directly use the common NumberToString implementation.
+
 2012-08-24  Oliver Hunt  <oliver@apple.com>
 
         Always null check cells before marking
index e3453201bf8e6f4498373e93146940e2491e3a9a..1b05f0aeceb4c749d44beed3a04b71e1119f0e80 100755 (executable)
@@ -265,12 +265,15 @@ EXPORTS
     ?notifyWriteSlow@WatchpointSet@JSC@@QAEXXZ
     ?nullptr@@3Vnullptr_t@std@@A
     ?number@String@WTF@@SA?AV12@NII@Z
-    ?number@UString@JSC@@SA?AV12@H@Z
-    ?number@UString@JSC@@SA?AV12@I@Z
-    ?number@UString@JSC@@SA?AV12@N@Z
     ?numberToFixedPrecisionString@WTF@@YAPBDNIQAD_N@Z
     ?numberToFixedWidthString@WTF@@YAPBDNIQAD@Z
     ?numberToString@WTF@@YAPBDNQAD@Z
+    ?numberToStringImpl@WTF@@YA?AV?$PassRefPtr@VStringImpl@WTF@@@1@_J@Z
+    ?numberToStringImpl@WTF@@YA?AV?$PassRefPtr@VStringImpl@WTF@@@1@_K@Z
+    ?numberToStringImpl@WTF@@YA?AV?$PassRefPtr@VStringImpl@WTF@@@1@H@Z
+    ?numberToStringImpl@WTF@@YA?AV?$PassRefPtr@VStringImpl@WTF@@@1@I@Z
+    ?numberToStringImpl@WTF@@YA?AV?$PassRefPtr@VStringImpl@WTF@@@1@J@Z
+    ?numberToStringImpl@WTF@@YA?AV?$PassRefPtr@VStringImpl@WTF@@@1@K@Z
     ?objectCount@Heap@JSC@@QAEIXZ
     ?objectProtoFuncToString@JSC@@YI_JPAVExecState@1@@Z
     ?objectTypeCounts@Heap@JSC@@QAE?AV?$PassOwnPtr@V?$HashCountedSet@PBDU?$PtrHash@PBD@WTF@@U?$HashTraits@PBD@2@@WTF@@@WTF@@XZ
index 5b1e9a0e0b12a0a7aefc627192562ab43377d4dc..c8c5885ba31004dee292ada7c7a42a08b3bd6ff0 100644 (file)
 #include "Identifier.h"
 #include "Operations.h"
 #include <ctype.h>
-#include <limits.h>
-#include <limits>
-#include <stdio.h>
 #include <stdlib.h>
 #include <wtf/ASCIICType.h>
 #include <wtf/Assertions.h>
 #include <wtf/MathExtras.h>
-#include <wtf/StringExtras.h>
 #include <wtf/Vector.h>
 #include <wtf/dtoa.h>
 #include <wtf/unicode/UTF8.h>
@@ -94,115 +90,6 @@ UString::UString(const char* characters)
 {
 }
 
-UString UString::number(int i)
-{
-    LChar buf[1 + sizeof(i) * 3];
-    LChar* end = buf + WTF_ARRAY_LENGTH(buf);
-    LChar* p = end;
-
-    if (i == 0)
-        *--p = '0';
-    else if (i == INT_MIN) {
-        char minBuf[1 + sizeof(i) * 3];
-        snprintf(minBuf, sizeof(minBuf), "%d", INT_MIN);
-        return UString(minBuf);
-    } else {
-        bool negative = false;
-        if (i < 0) {
-            negative = true;
-            i = -i;
-        }
-        while (i) {
-            *--p = static_cast<unsigned short>((i % 10) + '0');
-            i /= 10;
-        }
-        if (negative)
-            *--p = '-';
-    }
-
-    return UString(p, static_cast<unsigned>(end - p));
-}
-
-UString UString::number(long long i)
-{
-    LChar buf[1 + sizeof(i) * 3];
-    LChar* end = buf + WTF_ARRAY_LENGTH(buf);
-    LChar* p = end;
-
-    if (i == 0)
-        *--p = '0';
-    else if (i == std::numeric_limits<long long>::min()) {
-        char minBuf[1 + sizeof(i) * 3];
-#if OS(WINDOWS)
-        snprintf(minBuf, sizeof(minBuf), "%I64d", std::numeric_limits<long long>::min());
-#else
-        snprintf(minBuf, sizeof(minBuf), "%lld", std::numeric_limits<long long>::min());
-#endif
-        return UString(minBuf);
-    } else {
-        bool negative = false;
-        if (i < 0) {
-            negative = true;
-            i = -i;
-        }
-        while (i) {
-            *--p = static_cast<unsigned short>((i % 10) + '0');
-            i /= 10;
-        }
-        if (negative)
-            *--p = '-';
-    }
-
-    return UString(p, static_cast<unsigned>(end - p));
-}
-
-UString UString::number(unsigned u)
-{
-    LChar buf[sizeof(u) * 3];
-    LChar* end = buf + WTF_ARRAY_LENGTH(buf);
-    LChar* p = end;
-
-    if (u == 0)
-        *--p = '0';
-    else {
-        while (u) {
-            *--p = static_cast<unsigned short>((u % 10) + '0');
-            u /= 10;
-        }
-    }
-
-    return UString(p, static_cast<unsigned>(end - p));
-}
-
-UString UString::number(long l)
-{
-    LChar buf[1 + sizeof(l) * 3];
-    LChar* end = buf + WTF_ARRAY_LENGTH(buf);
-    LChar* p = end;
-
-    if (l == 0)
-        *--p = '0';
-    else if (l == LONG_MIN) {
-        char minBuf[1 + sizeof(l) * 3];
-        snprintf(minBuf, sizeof(minBuf), "%ld", LONG_MIN);
-        return UString(minBuf);
-    } else {
-        bool negative = false;
-        if (l < 0) {
-            negative = true;
-            l = -l;
-        }
-        while (l) {
-            *--p = static_cast<unsigned short>((l % 10) + '0');
-            l /= 10;
-        }
-        if (negative)
-            *--p = '-';
-    }
-
-    return UString(p, end - p);
-}
-
 UString UString::number(double d)
 {
     NumberToStringBuffer buffer;
index 7677161a36a5ce4942cd53a809f995957a4f7fc1..169bf4a371fa5e2da5e547b4614d4943c82f291b 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2012 Apple Inc. All rights reserved.
  * Copyright (C) 2009 Google Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
@@ -23,6 +23,7 @@
 #ifndef UString_h
 #define UString_h
 
+#include <wtf/text/IntegerToStringConversion.h>
 #include <wtf/text/StringImpl.h>
 
 namespace JSC {
@@ -112,10 +113,10 @@ public:
         return m_impl->characters16()[index];
     }
 
-    JS_EXPORT_PRIVATE static UString number(int);
-    JS_EXPORT_PRIVATE static UString number(unsigned);
-    JS_EXPORT_PRIVATE static UString number(long);
-    static UString number(long long);
+    static UString number(int i) { return WTF::numberToStringImpl(i); }
+    static UString number(unsigned u) { return WTF::numberToStringImpl(u); }
+    static UString number(long i) { return WTF::numberToStringImpl(i); }
+    static UString number(long long i) { return WTF::numberToStringImpl(i); }
     JS_EXPORT_PRIVATE static UString number(double);
 
     // Find a single character or string, also with match function & latin1 forms.
index c5a7d17bb187ebdfd0638d6187d09c04ec75a49e..8f8c0640277588777f6a1e8392a499a87e778e6d 100644 (file)
@@ -1,3 +1,38 @@
+2012-08-24  Benjamin Poulain  <bpoulain@apple.com>
+
+        Unify Number to StringImpl conversion
+        https://bugs.webkit.org/show_bug.cgi?id=94879
+
+        Reviewed by Geoffrey Garen.
+
+        Previously, UString::number() and String::number() used different implementations.
+
+        WTF::String::number() was simply forwarding to String::format().
+        UString::number() had an optimized version of the conversion.
+
+        This patch replace both implementation by a new version, faster than the two previous versions.
+
+        The new functions numberToStringImpl improvements are:
+        -about 3 times faster than String::number().
+        -14% faster than UString::number() on signed numbers.
+        -9% faster than UString::number() on unsigned numbers.
+
+        * GNUmakefile.list.am:
+        * WTF.gypi:
+        * WTF.pro:
+        * WTF.vcproj/WTF.vcproj:
+        * WTF.xcodeproj/project.pbxproj:
+        * wtf/CMakeLists.txt:
+        * wtf/text/IntegerToStringConversion.cpp: Added.
+        (WTF::numberToStringImplSigned):
+        (WTF::numberToStringImpl):
+        (WTF::numberToStringImplUnsigned):
+        * wtf/text/IntegerToStringConversion.h: Added.
+        * wtf/text/WTFString.cpp:
+        (WTF::String::format):
+        * wtf/text/WTFString.h:
+        (WTF::String::number):
+
 2012-08-24  Andras Becsi  <andras.becsi@nokia.com>
 
         [Qt] Be more explicit about the ICU dependency in the error message
index 7c123e537554b1857fc9a9266b6c225305953777..2283fed2c2dfcd1d28deba3533925ef0e605fb39 100644 (file)
@@ -208,6 +208,8 @@ wtf_sources += \
     Source/WTF/wtf/text/Base64.h \
     Source/WTF/wtf/text/CString.cpp \
     Source/WTF/wtf/text/CString.h \
+    Source/WTF/wtf/text/IntegerToStringConversion.cpp \
+    Source/WTF/wtf/text/IntegerToStringConversion.h \
     Source/WTF/wtf/text/StringBuffer.h \
     Source/WTF/wtf/text/StringBuilder.cpp \
     Source/WTF/wtf/text/StringBuilder.h \
index 531b4381d11f4ef93a4b09f4c6ffce17e505ccce..6cfcd421a7dbb56ce430a8953c2f7d6aea06a354 100644 (file)
             'wtf/text/AtomicStringImpl.h',
             'wtf/text/Base64.h',
             'wtf/text/CString.h',
+            'wtf/text/IntegerToStringConversion.h',
             'wtf/text/StringBuffer.h',
             'wtf/text/StringBuilder.h',
             'wtf/text/StringConcatenate.h',
             'wtf/text/AtomicString.cpp',
             'wtf/text/Base64.cpp',
             'wtf/text/CString.cpp',
+            'wtf/text/IntegerToStringConversion.cpp',
             'wtf/text/StringBuilder.cpp',
             'wtf/text/StringImpl.cpp',
             'wtf/text/StringStatics.cpp',
index f8223112db75099d252ed9c6b153f4b932b64299..106885d83574be8b2d23d20b9808ef9a8869961b 100644 (file)
@@ -135,6 +135,7 @@ HEADERS += \
     text/AtomicStringImpl.h \
     text/Base64.h \
     text/CString.h \
+    text/IntegerToStringConversion.h \
     text/StringBuffer.h \
     text/StringBuilder.h \
     text/StringConcatenate.h \
@@ -218,6 +219,7 @@ SOURCES += \
     text/AtomicString.cpp \
     text/Base64.cpp \
     text/CString.cpp \
+    text/IntegerToStringConversion.cpp \
     text/StringBuilder.cpp \
     text/StringImpl.cpp \
     text/StringStatics.cpp \
index 959edae34ea48088dabaefd751ef614d2b679707..d780375f9fce2fb4b8e8be63ac48577d74f968f3 100644 (file)
                                RelativePath="..\wtf\text\CString.h"
                                >
                        </File>
+                       <File
+                               RelativePath="..\wtf\text\IntegerToStringConversion.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\wtf\text\IntegerToStringConversion.h"
+                               >
+                       </File>
                        <File
                                RelativePath="..\wtf\text\StringBuffer.h"
                                >
index b26784f325995ccb92532559ae7f044d15edaf1b..288bdff4f9b4893b08fce692bd3fa480d74fb722 100644 (file)
@@ -11,6 +11,8 @@
                143F611F1565F0F900DB514A /* RAMSize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 143F611D1565F0F900DB514A /* RAMSize.cpp */; };
                143F61201565F0F900DB514A /* RAMSize.h in Headers */ = {isa = PBXBuildFile; fileRef = 143F611E1565F0F900DB514A /* RAMSize.h */; settings = {ATTRIBUTES = (Private, ); }; };
                14F3B0F715E45E4600210069 /* SaturatedArithmetic.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F3B0F615E45E4600210069 /* SaturatedArithmetic.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               26147B0915DDCCDC00DDB907 /* IntegerToStringConversion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26147B0715DDCCDC00DDB907 /* IntegerToStringConversion.cpp */; };
+               26147B0A15DDCCDC00DDB907 /* IntegerToStringConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 26147B0815DDCCDC00DDB907 /* IntegerToStringConversion.h */; };
                2C05385415BC819000F21B96 /* GregorianDateTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 2C05385315BC819000F21B96 /* GregorianDateTime.h */; };
                2CCD892A15C0390200285083 /* GregorianDateTime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2CCD892915C0390200285083 /* GregorianDateTime.cpp */; };
                4330F38F15745B0500AAFA8F /* URLString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4330F38E15745B0500AAFA8F /* URLString.cpp */; };
                143F611D1565F0F900DB514A /* RAMSize.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RAMSize.cpp; sourceTree = "<group>"; };
                143F611E1565F0F900DB514A /* RAMSize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RAMSize.h; sourceTree = "<group>"; };
                14F3B0F615E45E4600210069 /* SaturatedArithmetic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SaturatedArithmetic.h; sourceTree = "<group>"; };
+               26147B0715DDCCDC00DDB907 /* IntegerToStringConversion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntegerToStringConversion.cpp; sourceTree = "<group>"; };
+               26147B0815DDCCDC00DDB907 /* IntegerToStringConversion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntegerToStringConversion.h; sourceTree = "<group>"; };
                2C05385315BC819000F21B96 /* GregorianDateTime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GregorianDateTime.h; sourceTree = "<group>"; };
                2CCD892915C0390200285083 /* GregorianDateTime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GregorianDateTime.cpp; sourceTree = "<group>"; };
                4330F38E15745B0500AAFA8F /* URLString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = URLString.cpp; sourceTree = "<group>"; };
                                8134013715B092FD001FF0B8 /* Base64.h */,
                                A8A47321151A825B004123FF /* CString.cpp */,
                                A8A47322151A825B004123FF /* CString.h */,
+                               26147B0715DDCCDC00DDB907 /* IntegerToStringConversion.cpp */,
+                               26147B0815DDCCDC00DDB907 /* IntegerToStringConversion.h */,
                                A8A47323151A825B004123FF /* StringBuffer.h */,
                                A8A47324151A825B004123FF /* StringBuilder.cpp */,
                                A8A47325151A825B004123FF /* StringBuilder.h */,
                                A8A473DE151A825B004123FF /* Int16Array.h in Headers */,
                                A8A473DF151A825B004123FF /* Int32Array.h in Headers */,
                                A8A473DD151A825B004123FF /* Int8Array.h in Headers */,
+                               26147B0A15DDCCDC00DDB907 /* IntegerToStringConversion.h in Headers */,
                                A8A473E0151A825B004123FF /* IntegralTypedArrayBase.h in Headers */,
                                A8A473E1151A825B004123FF /* ListHashSet.h in Headers */,
                                A8A473E2151A825B004123FF /* ListRefPtr.h in Headers */,
                                A8A473B5151A825B004123FF /* fixed-dtoa.cc in Sources */,
                                2CCD892A15C0390200285083 /* GregorianDateTime.cpp in Sources */,
                                A8A473D8151A825B004123FF /* HashTable.cpp in Sources */,
+                               26147B0915DDCCDC00DDB907 /* IntegerToStringConversion.cpp in Sources */,
                                A8A473E5151A825B004123FF /* MainThread.cpp in Sources */,
                                A8A473E4151A825B004123FF /* MainThreadMac.mm in Sources */,
                                CD5497AC15857D0300B5BC30 /* MediaTime.cpp in Sources */,
index 543755904f9d856d39eeb8ad4cc53cad4ff3cae5..320c84be688b03991311c7dd705c4307cf99a000 100644 (file)
@@ -123,6 +123,7 @@ SET(WTF_HEADERS
     text/AtomicStringImpl.h
     text/Base64.h
     text/CString.h
+    text/IntegerToStringConversion.h
     text/StringBuffer.h
     text/StringHash.h
     text/StringImpl.h
@@ -182,6 +183,7 @@ SET(WTF_SOURCES
     text/AtomicString.cpp
     text/Base64.cpp
     text/CString.cpp
+    text/IntegerToStringConversion.cpp
     text/StringBuilder.cpp
     text/StringImpl.cpp
     text/StringStatics.cpp
diff --git a/Source/WTF/wtf/text/IntegerToStringConversion.cpp b/Source/WTF/wtf/text/IntegerToStringConversion.cpp
new file mode 100644 (file)
index 0000000..d95c883
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "IntegerToStringConversion.h"
+
+#include <wtf/text/StringImpl.h>
+
+namespace WTF {
+
+template<typename T> struct UnsignedIntegerTrait;
+
+template<> struct UnsignedIntegerTrait<short> {
+    typedef unsigned short Type;
+};
+template<> struct UnsignedIntegerTrait<int> {
+    typedef unsigned int Type;
+};
+template<> struct UnsignedIntegerTrait<long> {
+    typedef unsigned long Type;
+};
+template<> struct UnsignedIntegerTrait<long long> {
+    typedef unsigned long long Type;
+};
+
+template<typename SignedIntegerType>
+static PassRefPtr<StringImpl> numberToStringImplSigned(SignedIntegerType integer)
+{
+    LChar buf[1 + sizeof(SignedIntegerType) * 3];
+    LChar* end = buf + WTF_ARRAY_LENGTH(buf);
+    LChar* p = end;
+
+    bool negative = false;
+    typename UnsignedIntegerTrait<SignedIntegerType>::Type unsignedInteger;
+    if (integer < 0) {
+        negative = true;
+        unsignedInteger = -integer;
+    } else
+        unsignedInteger = integer;
+
+    do {
+        *--p = static_cast<LChar>((unsignedInteger % 10) + '0');
+        unsignedInteger /= 10;
+    } while (unsignedInteger);
+
+    if (negative)
+        *--p = '-';
+
+    return StringImpl::create(p, static_cast<unsigned>(end - p));
+}
+
+PassRefPtr<StringImpl> numberToStringImpl(int i)
+{
+    return numberToStringImplSigned(i);
+}
+
+PassRefPtr<StringImpl> numberToStringImpl(long i)
+{
+    return numberToStringImplSigned(i);
+}
+
+PassRefPtr<StringImpl> numberToStringImpl(long long i)
+{
+    return numberToStringImplSigned(i);
+}
+
+
+template<typename UnsignedIntegerType>
+PassRefPtr<StringImpl> numberToStringImplUnsigned(UnsignedIntegerType integer)
+{
+    LChar buf[sizeof(UnsignedIntegerType) * 3];
+    LChar* end = buf + WTF_ARRAY_LENGTH(buf);
+    LChar* p = end;
+
+    do {
+        *--p = static_cast<LChar>((integer % 10) + '0');
+        integer /= 10;
+    } while (integer);
+    return StringImpl::create(p, static_cast<unsigned>(end - p));
+}
+
+PassRefPtr<StringImpl> numberToStringImpl(unsigned u)
+{
+    return numberToStringImplUnsigned(u);
+}
+
+PassRefPtr<StringImpl> numberToStringImpl(unsigned long u)
+{
+    return numberToStringImplUnsigned(u);
+}
+
+PassRefPtr<StringImpl> numberToStringImpl(unsigned long long u)
+{
+    return numberToStringImplUnsigned(u);
+}
+
+} // namespace WTF
diff --git a/Source/WTF/wtf/text/IntegerToStringConversion.h b/Source/WTF/wtf/text/IntegerToStringConversion.h
new file mode 100644 (file)
index 0000000..c325059
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef IntegerToStringConversion_h
+#define IntegerToStringConversion_h
+
+#include "StringImpl.h"
+
+namespace WTF {
+WTF_EXPORT_STRING_API PassRefPtr<StringImpl> numberToStringImpl(int);
+WTF_EXPORT_STRING_API PassRefPtr<StringImpl> numberToStringImpl(long);
+WTF_EXPORT_STRING_API PassRefPtr<StringImpl> numberToStringImpl(long long);
+
+WTF_EXPORT_STRING_API PassRefPtr<StringImpl> numberToStringImpl(unsigned);
+WTF_EXPORT_STRING_API PassRefPtr<StringImpl> numberToStringImpl(unsigned long);
+WTF_EXPORT_STRING_API PassRefPtr<StringImpl> numberToStringImpl(unsigned long long);
+}
+
+#endif // IntegerToStringConversion_h
index fa3dad71f1d7902ee3966b036030dc46f7695f16..72b048d40a2baaf75ca3002c5cd29319a83c1cb1 100644 (file)
@@ -22,6 +22,7 @@
 #include "config.h"
 #include "WTFString.h"
 
+#include "IntegerToStringConversion.h"
 #include <stdarg.h>
 #include <wtf/ASCIICType.h>
 #include <wtf/DataLog.h>
@@ -416,54 +417,6 @@ String String::format(const char *format, ...)
     return StringImpl::create(reinterpret_cast<const LChar*>(buffer.data()), len);
 #endif
 }
-
-String String::number(short n)
-{
-    return String::format("%hd", n);
-}
-
-String String::number(unsigned short n)
-{
-    return String::format("%hu", n);
-}
-
-String String::number(int n)
-{
-    return String::format("%d", n);
-}
-
-String String::number(unsigned n)
-{
-    return String::format("%u", n);
-}
-
-String String::number(long n)
-{
-    return String::format("%ld", n);
-}
-
-String String::number(unsigned long n)
-{
-    return String::format("%lu", n);
-}
-
-String String::number(long long n)
-{
-#if OS(WINDOWS) && !PLATFORM(QT)
-    return String::format("%I64i", n);
-#else
-    return String::format("%lli", n);
-#endif
-}
-
-String String::number(unsigned long long n)
-{
-#if OS(WINDOWS) && !PLATFORM(QT)
-    return String::format("%I64u", n);
-#else
-    return String::format("%llu", n);
-#endif
-}
     
 String String::number(double number, unsigned flags, unsigned precision)
 {
index c781ae3d2eb9b8dae58a9dffdf3df0af929eb2d8..c543d563934ae765eb12ed3a0c3b2ac3ec28f32b 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * (C) 1999 Lars Knoll (knoll@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -26,6 +26,7 @@
 // on systems without case-sensitive file systems.
 
 #include <wtf/text/ASCIIFastPath.h>
+#include <wtf/text/IntegerToStringConversion.h>
 #include <wtf/text/StringImpl.h>
 
 #ifdef __OBJC__
@@ -220,14 +221,14 @@ public:
         return (*m_impl)[index];
     }
 
-    static String number(short);
-    WTF_EXPORT_STRING_API static String number(unsigned short);
-    WTF_EXPORT_STRING_API static String number(int);
-    WTF_EXPORT_STRING_API static String number(unsigned);
-    WTF_EXPORT_STRING_API static String number(long);
-    WTF_EXPORT_STRING_API static String number(unsigned long);
-    WTF_EXPORT_STRING_API static String number(long long);
-    WTF_EXPORT_STRING_API static String number(unsigned long long);
+    static String number(unsigned short number) { return numberToStringImpl(number); }
+    static String number(int number) { return numberToStringImpl(number); }
+    static String number(unsigned number) { return numberToStringImpl(number); }
+    static String number(long number) { return numberToStringImpl(number); }
+    static String number(unsigned long number) { return numberToStringImpl(number); }
+    static String number(long long number) { return numberToStringImpl(number); }
+    static String number(unsigned long long number) { return numberToStringImpl(number); }
+
     WTF_EXPORT_STRING_API static String number(double, unsigned = ShouldRoundSignificantFigures | ShouldTruncateTrailingZeros, unsigned precision = 6);
 
     // Find a single character or string, also with match function & latin1 forms.
index 88a207e47f209006a3e7337bc455d0fe74aabdf5..64eef084bf66fa2543cb830e8af6208fb1df2fa8 100644 (file)
@@ -1,3 +1,12 @@
+2012-08-24  Benjamin Poulain  <bpoulain@apple.com>
+
+        Unify Number to StringImpl conversion
+        https://bugs.webkit.org/show_bug.cgi?id=94879
+
+        Reviewed by Geoffrey Garen.
+
+        * win/WebKit2.def: Update the exported symbols.
+
 2012-08-24  Andras Becsi  <andras.becsi@nokia.com>
 
         [Qt][WK2] Fix custom device pixel ratio propagation and add QML API tests
index 5f68abc3a6dc2057984fcebcf4cd60ce2971b243..1bf078f5b7e0a62882f04553d632546d8cbe9726 100644 (file)
@@ -195,8 +195,8 @@ EXPORTS
         ?lastChild@ComposedShadowTreeWalker@WebCore@@QAEXXZ
         ?next@ComposedShadowTreeWalker@WebCore@@QAEXXZ
         ?previous@ComposedShadowTreeWalker@WebCore@@QAEXXZ
-        ?number@String@WTF@@SA?AV12@I@Z
-        ?number@String@WTF@@SA?AV12@H@Z
+        ?numberToStringImpl@WTF@@YA?AV?$PassRefPtr@VStringImpl@WTF@@@1@H@Z
+        ?numberToStringImpl@WTF@@YA?AV?$PassRefPtr@VStringImpl@WTF@@@1@I@Z
         ?overrideUserPreferredLanguages@WebCore@@YAXABV?$Vector@VString@WTF@@$0A@@WTF@@@Z
         ?numberOfScopedHTMLStyleChildren@Node@WebCore@@QBEIXZ
         ?page@Document@WebCore@@QBEPAVPage@2@XZ
index b4d3e761e2d5099d3ba35355c6700f4ba9f28f38..51a7991ea0ddf9bebea7e1f94f681ac6953c4bf4 100644 (file)
@@ -1,3 +1,17 @@
+2012-08-24  Benjamin Poulain  <bpoulain@apple.com>
+
+        Unify Number to StringImpl conversion
+        https://bugs.webkit.org/show_bug.cgi?id=94879
+
+        Reviewed by Geoffrey Garen.
+
+        Add testing for the new IntegerToStringConversion.
+
+        * TestWebKitAPI/CMakeLists.txt:
+        * TestWebKitAPI/GNUmakefile.am:
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WTF/IntegerToStringConversion.cpp: Added.
+
 2012-08-23  James Robinson  <jamesr@chromium.org>
 
         [chromium] Convert WebLayerTreeView interface into pure virtual
index 5afadba2b628a2f9b9eec80b18355d7197378df1..5101f37f51e07e5175d2ad7c169b712652163e9b 100644 (file)
@@ -71,6 +71,7 @@ ADD_EXECUTABLE(test_wtf
     ${TESTWEBKITAPI_DIR}/Tests/WTF/CheckedArithmeticOperations.cpp
     ${TESTWEBKITAPI_DIR}/Tests/WTF/Functional.cpp
     ${TESTWEBKITAPI_DIR}/Tests/WTF/HashMap.cpp
+    ${TESTWEBKITAPI_DIR}/Tests/WTF/IntegerToStringConversion.cpp
     ${TESTWEBKITAPI_DIR}/Tests/WTF/MetaAllocator.cpp
     ${TESTWEBKITAPI_DIR}/Tests/WTF/RedBlackTree.cpp
     ${TESTWEBKITAPI_DIR}/Tests/WTF/SaturatedArithmeticOperations.cpp
index 56f430006df357d060ea9304ab0937d775f63ba4..566d245c772c882abed033cba1b1f8ce10e58578 100644 (file)
@@ -55,6 +55,7 @@ Programs_TestWebKitAPI_TestWTF_SOURCES = \
        Tools/TestWebKitAPI/Tests/WTF/CheckedArithmeticOperations.cpp \
        Tools/TestWebKitAPI/Tests/WTF/Functional.cpp \
        Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp \
+       Tools/TestWebKitAPI/Tests/WTF/IntegerToStringConversion.cpp \
        Tools/TestWebKitAPI/Tests/WTF/MediaTime.cpp \
        Tools/TestWebKitAPI/Tests/WTF/RedBlackTree.cpp \
        Tools/TestWebKitAPI/Tests/WTF/SaturatedArithmeticOperations.cpp \
index 9576250f24f682a258a72b0ed5e44f95634752d9..f79a33e7f14c3c2cf7e94c45cd6d66413399b936 100644 (file)
@@ -24,6 +24,7 @@
                1AEDE22613E5E7E700E62FE8 /* InjectedBundleControllerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1AEDE22413E5E7A000E62FE8 /* InjectedBundleControllerMac.mm */; };
                261516D615B0E60500A2C201 /* SetAndUpdateCacheModel.mm in Sources */ = {isa = PBXBuildFile; fileRef = 261516D515B0E60500A2C201 /* SetAndUpdateCacheModel.mm */; };
                265AF55015D1E48A00B0CB4A /* WTFString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 265AF54F15D1E48A00B0CB4A /* WTFString.cpp */; };
+               266FAFD315E5775200F61D5B /* IntegerToStringConversion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266FAFD215E5775200F61D5B /* IntegerToStringConversion.cpp */; };
                26A2C72F15E2E73C005B1A14 /* CString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A2C72E15E2E73C005B1A14 /* CString.cpp */; };
                26B2DFF915BDE599004F691D /* HashSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26B2DFF815BDE599004F691D /* HashSet.cpp */; };
                26DF5A5E15A29BAA003689C2 /* CancelLoadFromResourceLoadDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26DF5A5D15A29BAA003689C2 /* CancelLoadFromResourceLoadDelegate.mm */; };
                1AEDE22413E5E7A000E62FE8 /* InjectedBundleControllerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = InjectedBundleControllerMac.mm; sourceTree = "<group>"; };
                261516D515B0E60500A2C201 /* SetAndUpdateCacheModel.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SetAndUpdateCacheModel.mm; sourceTree = "<group>"; };
                265AF54F15D1E48A00B0CB4A /* WTFString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WTFString.cpp; path = WTF/WTFString.cpp; sourceTree = "<group>"; };
+               266FAFD215E5775200F61D5B /* IntegerToStringConversion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IntegerToStringConversion.cpp; path = WTF/IntegerToStringConversion.cpp; sourceTree = "<group>"; };
                26A2C72E15E2E73C005B1A14 /* CString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CString.cpp; path = WTF/CString.cpp; sourceTree = "<group>"; };
                26B2DFF815BDE599004F691D /* HashSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HashSet.cpp; path = WTF/HashSet.cpp; sourceTree = "<group>"; };
                26DF5A5D15A29BAA003689C2 /* CancelLoadFromResourceLoadDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CancelLoadFromResourceLoadDelegate.mm; sourceTree = "<group>"; };
                                0BCD833414857CE400EA2003 /* HashMap.cpp */,
                                26B2DFF815BDE599004F691D /* HashSet.cpp */,
                                14F3B11215E45EAB00210069 /* SaturatedArithmeticOperations.cpp */,
+                               266FAFD215E5775200F61D5B /* IntegerToStringConversion.cpp */,
                                81B50192140F232300D9EB58 /* StringBuilder.cpp */,
                                26F1B44315CA434F00D1E4BF /* StringImpl.cpp */,
                                C01363C713C3997300EF3964 /* StringOperators.cpp */,
                                C507E8A714C6545B005D6B3B /* InspectorBar.mm in Sources */,
                                C08587FC13FEC39B001EF4E5 /* InstanceMethodSwizzler.mm in Sources */,
                                C085880013FEC3A6001EF4E5 /* InstanceMethodSwizzler.mm in Sources */,
+                               266FAFD315E5775200F61D5B /* IntegerToStringConversion.cpp in Sources */,
                                C0ADBE7C12FCA4D000D2C129 /* JavaScriptTest.cpp in Sources */,
                                C081224213FC172400DC39AE /* JavaScriptTestMac.mm in Sources */,
                                440A1D3914A0103A008A66F2 /* KURL.cpp in Sources */,
diff --git a/Tools/TestWebKitAPI/Tests/WTF/IntegerToStringConversion.cpp b/Tools/TestWebKitAPI/Tests/WTF/IntegerToStringConversion.cpp
new file mode 100644 (file)
index 0000000..a201f41
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <limits>
+#include <wtf/StringExtras.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/IntegerToStringConversion.h>
+#include <wtf/text/WTFString.h>
+
+template<typename IntegerType> struct PrintfFormatTrait { static const char format[]; };
+
+template<> struct PrintfFormatTrait<short> { static const char format[]; };
+const char PrintfFormatTrait<short>::format[] = "%hd";
+
+template<> struct PrintfFormatTrait<int> { static const char format[]; };
+const char PrintfFormatTrait<int>::format[] = "%d";
+
+template<> struct PrintfFormatTrait<long> { static const char format[]; };
+const char PrintfFormatTrait<long>::format[] = "%ld";
+
+template<> struct PrintfFormatTrait<long long> { static const char format[]; };
+#if OS(WINDOWS) && !PLATFORM(QT)
+const char PrintfFormatTrait<long long>::format[] = "%I64i";
+#else
+const char PrintfFormatTrait<long long>::format[] = "%lli";
+#endif // OS(WINDOWS) && !PLATFORM(QT)
+
+template<> struct PrintfFormatTrait<unsigned short> { static const char format[]; };
+const char PrintfFormatTrait<unsigned short>::format[] = "%hu";
+
+template<> struct PrintfFormatTrait<unsigned> { static const char format[]; };
+const char PrintfFormatTrait<unsigned>::format[] = "%u";
+
+template<> struct PrintfFormatTrait<unsigned long> { static const char format[]; };
+const char PrintfFormatTrait<unsigned long>::format[] = "%lu";
+
+template<> struct PrintfFormatTrait<unsigned long long> { static const char format[]; };
+#if OS(WINDOWS) && !PLATFORM(QT)
+const char PrintfFormatTrait<unsigned long long>::format[] = "%I64u";
+#else
+const char PrintfFormatTrait<unsigned long long>::format[] = "%llu";
+#endif // OS(WINDOWS) && !PLATFORM(QT)
+
+
+// FIXME: use snprintf from StringExtras.h
+template<typename IntegerType>
+void testBoundaries()
+{
+    const unsigned bufferSize = 256;
+    Vector<char, bufferSize> buffer;
+    buffer.resize(bufferSize);
+
+    const IntegerType min = std::numeric_limits<IntegerType>::min();
+    CString minStringData = String(WTF::numberToStringImpl(min)).latin1();
+    snprintf(buffer.data(), bufferSize, PrintfFormatTrait<IntegerType>::format, min);
+    ASSERT_STREQ(buffer.data(), minStringData.data());
+
+    const IntegerType max = std::numeric_limits<IntegerType>::max();
+    CString maxStringData = String(WTF::numberToStringImpl(max)).latin1();
+    snprintf(buffer.data(), bufferSize, PrintfFormatTrait<IntegerType>::format, max);
+    ASSERT_STREQ(buffer.data(), maxStringData.data());
+}
+
+template<typename IntegerType>
+void testNumbers()
+{
+    const unsigned bufferSize = 256;
+    Vector<char, bufferSize> buffer;
+    buffer.resize(bufferSize);
+
+    for (int i = -100; i < 100; ++i) {
+        const IntegerType number = static_cast<IntegerType>(i);
+        CString numberStringData = String(WTF::numberToStringImpl(number)).latin1();
+        snprintf(buffer.data(), bufferSize, PrintfFormatTrait<IntegerType>::format, number);
+        ASSERT_STREQ(buffer.data(), numberStringData.data());
+    }
+}
+
+TEST(WTF, IntegerToStringConversionSignedIntegerBoundaries)
+{
+    testBoundaries<short>();
+    testBoundaries<int>();
+    testBoundaries<long>();
+    testBoundaries<long long>();
+}
+
+TEST(WTF, IntegerToStringConversionSignedIntegerRegularNumbers)
+{
+    testNumbers<short>();
+    testNumbers<int>();
+    testNumbers<long>();
+    testNumbers<long long>();
+}
+
+TEST(WTF, IntegerToStringConversionUnsignedIntegerBoundaries)
+{
+    testBoundaries<unsigned short>();
+    testBoundaries<unsigned int>();
+    testBoundaries<unsigned long>();
+    testBoundaries<unsigned long long>();
+}
+
+TEST(WTF, IntegerToStringConversionUnsignedIntegerRegularNumbers)
+{
+    testNumbers<unsigned short>();
+    testNumbers<unsigned int>();
+    testNumbers<unsigned long>();
+    testNumbers<unsigned long long>();
+}