Changeset 51168 in webkit


Ignore:
Timestamp:
Nov 18, 2009 7:12:50 PM (14 years ago)
Author:
tkent@chromium.org
Message:

2009-11-18 Kent Tamura <tkent@chromium.org>

Reviewed by Darin Adler.

Move UString::from(double) implementation to new
WTF::doubleToStringInJavaScriptFormat(), and expose it because WebCore
code will use it.
https://bugs.webkit.org/show_bug.cgi?id=31330

  • Introduce new function createRep(const char*, unsigned) and UString::UString(const char*, unsigned) to reduce 2 calls to strlen().
  • Fix a bug that dtoa() doesn't update *rve if the input value is NaN or Infinity.

No new tests because this doesn't change the behavior.

  • JavaScriptCore.exp:
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
  • runtime/UString.cpp: (JSC::createRep): (JSC::UString::UString): (JSC::UString::from): Move the code to doubleToStringInJavaScriptFormat().
  • runtime/UString.h:
  • wtf/dtoa.cpp: (WTF::dtoa): Fix a bug about rve. (WTF::append): A helper for doubleToStringInJavaScriptFormat(). (WTF::doubleToStringInJavaScriptFormat): Move the code from UString::from(double).
  • wtf/dtoa.h:
Location:
trunk/JavaScriptCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r51166 r51168  
     12009-11-18  Kent Tamura  <tkent@chromium.org>
     2
     3        Reviewed by Darin Adler.
     4
     5        Move UString::from(double) implementation to new
     6        WTF::doubleToStringInJavaScriptFormat(), and expose it because WebCore
     7        code will use it.
     8        https://bugs.webkit.org/show_bug.cgi?id=31330
     9
     10        - Introduce new function createRep(const char*, unsigned) and
     11          UString::UString(const char*, unsigned) to reduce 2 calls to strlen().
     12        - Fix a bug that dtoa() doesn't update *rve if the input value is NaN
     13          or Infinity.
     14
     15        No new tests because this doesn't change the behavior.
     16
     17        * JavaScriptCore.exp:
     18        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
     19        * runtime/UString.cpp:
     20        (JSC::createRep):
     21        (JSC::UString::UString):
     22        (JSC::UString::from): Move the code to doubleToStringInJavaScriptFormat().
     23        * runtime/UString.h:
     24        * wtf/dtoa.cpp:
     25        (WTF::dtoa): Fix a bug about rve.
     26        (WTF::append): A helper for doubleToStringInJavaScriptFormat().
     27        (WTF::doubleToStringInJavaScriptFormat): Move the code from UString::from(double).
     28        * wtf/dtoa.h:
     29
    1302009-11-18  Laszlo Gombos  <laszlo.1.gombos@nokia.com>
    231
  • trunk/JavaScriptCore/JavaScriptCore.exp

    r50706 r51168  
    332332__ZN3WTF27releaseFastMallocFreeMemoryEv
    333333__ZN3WTF28setMainThreadCallbacksPausedEb
     334__ZN3WTF32doubleToStringInJavaScriptFormatEdPcPj
    334335__ZN3WTF36lockAtomicallyInitializedStaticMutexEv
    335336__ZN3WTF37parseDateFromNullTerminatedCharactersEPKc
  • trunk/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def

    r50915 r51168  
    115115    ?didTimeOut@TimeoutChecker@JSC@@QAE_NPAVExecState@2@@Z
    116116    ?dumpSampleData@JSGlobalData@JSC@@QAEXPAVExecState@2@@Z
     117    ?doubleToStringInJavaScriptFormat@WTF@@YAXNQADPAI@Z
    117118    ?enumerable@PropertyDescriptor@JSC@@QBE_NXZ
    118119    ?equal@Identifier@JSC@@SA_NPBURep@UString@2@PBD@Z
  • trunk/JavaScriptCore/runtime/UString.cpp

    r48298 r51168  
    579579}
    580580
     581static inline PassRefPtr<UString::Rep> createRep(const char* c, int length)
     582{
     583    if (!c)
     584        return &UString::Rep::null();
     585
     586    if (!length)
     587        return &UString::Rep::empty();
     588
     589    UChar* d;
     590    if (!allocChars(length).getValue(d))
     591        return &UString::Rep::null();
     592
     593    for (int i = 0; i < length; i++)
     594        d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend
     595    return UString::Rep::create(d, length);
     596}
     597
    581598UString::UString(const char* c)
    582599    : m_rep(createRep(c))
     600{
     601}
     602
     603UString::UString(const char* c, int length)
     604    : m_rep(createRep(c, length))
    583605{
    584606}
     
    10261048UString UString::from(double d)
    10271049{
    1028     // avoid ever printing -NaN, in JS conceptually there is only one NaN value
    1029     if (isnan(d))
    1030         return "NaN";
    1031     if (!d)
    1032         return "0"; // -0 -> "0"
    1033 
    1034     char buf[80];
    1035     int decimalPoint;
    1036     int sign;
    1037    
    1038     char result[80];
    1039     WTF::dtoa(result, d, 0, &decimalPoint, &sign, NULL);
    1040     int length = static_cast<int>(strlen(result));
    1041  
    1042     int i = 0;
    1043     if (sign)
    1044         buf[i++] = '-';
    1045  
    1046     if (decimalPoint <= 0 && decimalPoint > -6) {
    1047         buf[i++] = '0';
    1048         buf[i++] = '.';
    1049         for (int j = decimalPoint; j < 0; j++)
    1050             buf[i++] = '0';
    1051         strcpy(buf + i, result);
    1052     } else if (decimalPoint <= 21 && decimalPoint > 0) {
    1053         if (length <= decimalPoint) {
    1054             strcpy(buf + i, result);
    1055             i += length;
    1056             for (int j = 0; j < decimalPoint - length; j++)
    1057                 buf[i++] = '0';
    1058             buf[i] = '\0';
    1059         } else {
    1060             strncpy(buf + i, result, decimalPoint);
    1061             i += decimalPoint;
    1062             buf[i++] = '.';
    1063             strcpy(buf + i, result + decimalPoint);
    1064         }
    1065     } else if (result[0] < '0' || result[0] > '9')
    1066         strcpy(buf + i, result);
    1067     else {
    1068         buf[i++] = result[0];
    1069         if (length > 1) {
    1070             buf[i++] = '.';
    1071             strcpy(buf + i, result + 1);
    1072             i += length - 1;
    1073         }
    1074        
    1075         buf[i++] = 'e';
    1076         buf[i++] = (decimalPoint >= 0) ? '+' : '-';
    1077         // decimalPoint can't be more than 3 digits decimal given the
    1078         // nature of float representation
    1079         int exponential = decimalPoint - 1;
    1080         if (exponential < 0)
    1081             exponential = -exponential;
    1082         if (exponential >= 100)
    1083             buf[i++] = static_cast<char>('0' + exponential / 100);
    1084         if (exponential >= 10)
    1085             buf[i++] = static_cast<char>('0' + (exponential % 100) / 10);
    1086         buf[i++] = static_cast<char>('0' + exponential % 10);
    1087         buf[i++] = '\0';
    1088     }
    1089    
    1090     return UString(buf);
     1050    DtoaBuffer buffer;
     1051    unsigned length;
     1052    doubleToStringInJavaScriptFormat(d, buffer, &length);
     1053    return UString(buffer, length);
    10911054}
    10921055
  • trunk/JavaScriptCore/runtime/UString.h

    r47622 r51168  
    236236    public:
    237237        UString();
     238        // Constructor for null-terminated ASCII string.
    238239        UString(const char*);
     240        // Constructor for non-null-terminated ASCII string.
     241        UString(const char*, int length);
    239242        UString(const UChar*, int length);
    240243        UString(UChar*, int length, bool copy);
  • trunk/JavaScriptCore/wtf/dtoa.cpp

    r48248 r51168  
    149149#include <wtf/Assertions.h>
    150150#include <wtf/FastMalloc.h>
     151#include <wtf/MathExtras.h>
    151152#include <wtf/Vector.h>
    152153#include <wtf/Threading.h>
     
    18701871 */
    18711872
    1872 void dtoa(char* result, double dd, int ndigits, int* decpt, int* sign, char** rve)
     1873void dtoa(DtoaBuffer result, double dd, int ndigits, int* decpt, int* sign, char** rve)
    18731874{
    18741875    /*
     
    19091910        /* Infinity or NaN */
    19101911        *decpt = 9999;
    1911         if (!word1(&u) && !(word0(&u) & 0xfffff))
     1912        if (!word1(&u) && !(word0(&u) & 0xfffff)) {
    19121913            strcpy(result, "Infinity");
    1913         else
     1914            if (rve)
     1915                *rve = result + 8;
     1916        } else {
    19141917            strcpy(result, "NaN");
     1918            if (rve)
     1919                *rve = result + 3;
     1920        }
    19151921        return;
    19161922    }
     
    19191925        result[0] = '0';
    19201926        result[1] = '\0';
     1927        if (rve)
     1928            *rve = result + 1;
    19211929        return;
    19221930    }
     
    23772385}
    23782386
     2387static ALWAYS_INLINE void append(char*& next, const char* src, unsigned size)
     2388{
     2389    for (unsigned i = 0; i < size; ++i)
     2390        *next++ = *src++;
     2391}
     2392
     2393void doubleToStringInJavaScriptFormat(double d, DtoaBuffer buffer, unsigned* resultLength)
     2394{
     2395    ASSERT(buffer);
     2396
     2397    // avoid ever printing -NaN, in JS conceptually there is only one NaN value
     2398    if (isnan(d)) {
     2399        append(buffer, "NaN", 3);
     2400        if (resultLength)
     2401            *resultLength = 3;
     2402        return;
     2403    }
     2404    // -0 -> "0"
     2405    if (!d) {
     2406        buffer[0] = '0';
     2407        if (resultLength)
     2408            *resultLength = 1;
     2409        return;
     2410    }
     2411
     2412    int decimalPoint;
     2413    int sign;
     2414
     2415    DtoaBuffer result;
     2416    char* resultEnd = 0;
     2417    WTF::dtoa(result, d, 0, &decimalPoint, &sign, &resultEnd);
     2418    int length = resultEnd - result;
     2419
     2420    char* next = buffer;
     2421    if (sign)
     2422        *next++ = '-';
     2423
     2424    if (decimalPoint <= 0 && decimalPoint > -6) {
     2425        *next++ = '0';
     2426        *next++ = '.';
     2427        for (int j = decimalPoint; j < 0; j++)
     2428            *next++ = '0';
     2429        append(next, result, length);
     2430    } else if (decimalPoint <= 21 && decimalPoint > 0) {
     2431        if (length <= decimalPoint) {
     2432            append(next, result, length);
     2433            for (int j = 0; j < decimalPoint - length; j++)
     2434                *next++ = '0';
     2435        } else {
     2436            append(next, result, decimalPoint);
     2437            *next++ = '.';
     2438            append(next, result + decimalPoint, length - decimalPoint);
     2439        }
     2440    } else if (result[0] < '0' || result[0] > '9')
     2441        append(next, result, length);
     2442    else {
     2443        *next++ = result[0];
     2444        if (length > 1) {
     2445            *next++ = '.';
     2446            append(next, result + 1, length - 1);
     2447        }
     2448
     2449        *next++ = 'e';
     2450        *next++ = (decimalPoint >= 0) ? '+' : '-';
     2451        // decimalPoint can't be more than 3 digits decimal given the
     2452        // nature of float representation
     2453        int exponential = decimalPoint - 1;
     2454        if (exponential < 0)
     2455            exponential = -exponential;
     2456        if (exponential >= 100)
     2457            *next++ = static_cast<char>('0' + exponential / 100);
     2458        if (exponential >= 10)
     2459            *next++ = static_cast<char>('0' + (exponential % 100) / 10);
     2460        *next++ = static_cast<char>('0' + exponential % 10);
     2461    }
     2462    if (resultLength)
     2463        *resultLength = next - buffer;
     2464}
     2465
    23792466} // namespace WTF
  • trunk/JavaScriptCore/wtf/dtoa.h

    r44224 r51168  
    3131
    3232    double strtod(const char* s00, char** se);
    33     void dtoa(char* result, double d, int ndigits, int* decpt, int* sign, char** rve);
     33
     34    typedef char DtoaBuffer[80];
     35    void dtoa(DtoaBuffer result, double d, int ndigits, int* decpt, int* sign, char** rve);
     36
     37    // dtoa() for ECMA-262 'ToString Applied to the Number Type.'
     38    // The *resultLength will have the length of the resultant string in bufer.
     39    // The resultant string isn't terminated by 0.
     40    void doubleToStringInJavaScriptFormat(double, DtoaBuffer, unsigned* resultLength);
    3441
    3542} // namespace WTF
    3643
     44using WTF::DtoaBuffer;
     45using WTF::doubleToStringInJavaScriptFormat;
     46
    3747#endif // WTF_dtoa_h
Note: See TracChangeset for help on using the changeset viewer.