Changeset 88587 in webkit


Ignore:
Timestamp:
Jun 10, 2011 7:03:00 PM (13 years ago)
Author:
barraclough@apple.com
Message:

https://bugs.webkit.org/show_bug.cgi?id=16777
Eliminate JSC::NaN and JSC::Inf

Reviewed by Sam Weinig.

There's no good reason for -K-J-S- JSC to have its own NAN and infinity constants.
The ones in std::numeric_limits are perfectly good.

Remove JSC::Inf, JSC::NaN, switch some cases of (isnan
isinf) to !isfinite.

Source/JavaScriptCore:

  • API/JSCallbackObjectFunctions.h:

(JSC::::toNumber):

  • API/JSValueRef.cpp:

(JSValueMakeNumber):
(JSValueToNumber):

(JSC::CachedTranscendentalFunction::initialize):

  • runtime/DateConstructor.cpp:

(JSC::constructDate):

  • runtime/DateInstanceCache.h:

(JSC::DateInstanceData::DateInstanceData):
(JSC::DateInstanceCache::reset):

  • runtime/JSCell.cpp:
  • runtime/JSCell.h:

(JSC::JSCell::JSValue::getPrimitiveNumber):
(JSC::JSCell::JSValue::toNumber):

  • runtime/JSGlobalData.cpp:

(JSC::JSGlobalData::JSGlobalData):
(JSC::JSGlobalData::resetDateCache):

  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::reset):

  • runtime/JSGlobalObjectFunctions.cpp:

(JSC::globalFuncParseInt):
(JSC::globalFuncIsFinite):

  • runtime/JSNotAnObject.cpp:

(JSC::JSNotAnObject::toNumber):

  • runtime/JSValue.cpp:
  • runtime/JSValue.h:
  • runtime/JSValueInlineMethods.h:

(JSC::jsNaN):

  • runtime/MathObject.cpp:

(JSC::mathProtoFuncMax):
(JSC::mathProtoFuncMin):

  • runtime/NumberConstructor.cpp:

(JSC::numberConstructorNegInfinity):
(JSC::numberConstructorPosInfinity):

  • runtime/NumberPrototype.cpp:

(JSC::numberProtoFuncToExponential):
(JSC::numberProtoFuncToFixed):
(JSC::numberProtoFuncToPrecision):
(JSC::numberProtoFuncToString):

  • runtime/UString.cpp:
  • wtf/DecimalNumber.h:

(WTF::DecimalNumber::DecimalNumber):

  • wtf/dtoa.cpp:

(WTF::dtoa):

Source/WebCore:

  • bindings/js/JSDataViewCustom.cpp:

(WebCore::getDataViewMember):

Location:
trunk/Source
Files:
25 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h

    r87588 r88587  
    445445    // primitive
    446446    if (exec->hadException())
    447         return NaN;
     447        return std::numeric_limits<double>::quiet_NaN();
    448448    JSContextRef ctx = toRef(exec);
    449449    JSObjectRef thisRef = toRef(this);
     
    464464            double dValue;
    465465            if (value)
    466                 return toJS(exec, value).getNumber(dValue) ? dValue : NaN;
     466                return toJS(exec, value).getNumber(dValue) ? dValue : std::numeric_limits<double>::quiet_NaN();
    467467        }
    468468           
  • trunk/Source/JavaScriptCore/API/JSValueRef.cpp

    r79132 r88587  
    218218    // but an external NaN might not.
    219219    if (isnan(value))
    220         value = NaN;
     220        value = std::numeric_limits<double>::quiet_NaN();
    221221
    222222    return toRef(exec, jsNumber(value));
     
    277277            *exception = toRef(exec, exec->exception());
    278278        exec->clearException();
    279         number = NaN;
     279        number = std::numeric_limits<double>::quiet_NaN();
    280280    }
    281281    return number;
  • trunk/Source/JavaScriptCore/ChangeLog

    r88576 r88587  
     12011-06-10  Gavin Barraclough  <barraclough@apple.com>
     2
     3        Reviewed by Sam Weinig.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=16777
     6        Eliminate JSC::NaN and JSC::Inf
     7
     8        There's no good reason for -K-J-S- JSC to have its own NAN and infinity constants.
     9        The ones in std::numeric_limits are perfectly good.
     10        Remove JSC::Inf, JSC::NaN, switch some cases of (isnan || isinf) to !isfinite.
     11
     12        * API/JSCallbackObjectFunctions.h:
     13        (JSC::::toNumber):
     14        * API/JSValueRef.cpp:
     15        (JSValueMakeNumber):
     16        (JSValueToNumber):
     17        * JavaScriptCore.exp:
     18        * runtime/CachedTranscendentalFunction.h:
     19        (JSC::CachedTranscendentalFunction::initialize):
     20        * runtime/DateConstructor.cpp:
     21        (JSC::constructDate):
     22        * runtime/DateInstanceCache.h:
     23        (JSC::DateInstanceData::DateInstanceData):
     24        (JSC::DateInstanceCache::reset):
     25        * runtime/JSCell.cpp:
     26        * runtime/JSCell.h:
     27        (JSC::JSCell::JSValue::getPrimitiveNumber):
     28        (JSC::JSCell::JSValue::toNumber):
     29        * runtime/JSGlobalData.cpp:
     30        (JSC::JSGlobalData::JSGlobalData):
     31        (JSC::JSGlobalData::resetDateCache):
     32        * runtime/JSGlobalObject.cpp:
     33        (JSC::JSGlobalObject::reset):
     34        * runtime/JSGlobalObjectFunctions.cpp:
     35        (JSC::globalFuncParseInt):
     36        (JSC::globalFuncIsFinite):
     37        * runtime/JSNotAnObject.cpp:
     38        (JSC::JSNotAnObject::toNumber):
     39        * runtime/JSValue.cpp:
     40        * runtime/JSValue.h:
     41        * runtime/JSValueInlineMethods.h:
     42        (JSC::jsNaN):
     43        * runtime/MathObject.cpp:
     44        (JSC::mathProtoFuncMax):
     45        (JSC::mathProtoFuncMin):
     46        * runtime/NumberConstructor.cpp:
     47        (JSC::numberConstructorNegInfinity):
     48        (JSC::numberConstructorPosInfinity):
     49        * runtime/NumberPrototype.cpp:
     50        (JSC::numberProtoFuncToExponential):
     51        (JSC::numberProtoFuncToFixed):
     52        (JSC::numberProtoFuncToPrecision):
     53        (JSC::numberProtoFuncToString):
     54        * runtime/UString.cpp:
     55        * wtf/DecimalNumber.h:
     56        (WTF::DecimalNumber::DecimalNumber):
     57        * wtf/dtoa.cpp:
     58        (WTF::dtoa):
     59
    1602011-06-10  Tony Chang  <tony@chromium.org>
    261
  • trunk/Source/JavaScriptCore/JavaScriptCore.exp

    r88473 r88587  
    149149__ZN3JSC12StringObject6s_infoE
    150150__ZN3JSC12StringObjectC2EPNS_9ExecStateEPNS_9StructureERKNS_7UStringE
    151 __ZN3JSC12nonInlineNaNEv
    152151__ZN3JSC13SamplingFlags4stopEv
    153152__ZN3JSC13SamplingFlags5startEv
     
    220219__ZN3JSC25evaluateInGlobalCallFrameERKNS_7UStringERNS_7JSValueEPNS_14JSGlobalObjectE
    221220__ZN3JSC35createInterruptedExecutionExceptionEPNS_12JSGlobalDataE
    222 __ZN3JSC3NaNE
    223221__ZN3JSC41constructFunctionSkippingEvalEnabledCheckEPNS_9ExecStateEPNS_14JSGlobalObjectERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi
    224222__ZN3JSC4Heap11objectCountEv
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def

    r88473 r88587  
    4444    ??8JSC@@YA_NABVUString@0@0@Z
    4545    ??8WTF@@YA_NABVCString@0@0@Z
    46     ?NaN@JSC@@3NB
    4746    ?absoluteTimeToWaitTimeoutInterval@WTF@@YAKN@Z
    4847    ?activityCallback@Heap@JSC@@QAEPAVGCActivityCallback@2@XZ
     
    248247    ?name@JSFunction@JSC@@QAEABVUString@2@PAVExecState@2@@Z
    249248    ?newUninitialized@CString@WTF@@SA?AV12@IAAPAD@Z
    250     ?nonInlineNaN@JSC@@YANXZ
    251249    ?nullptr@@3Vnullptr_t@std@@A
    252250    ?number@UString@JSC@@SA?AV12@H@Z
  • trunk/Source/JavaScriptCore/runtime/CachedTranscendentalFunction.h

    r70496 r88587  
    3030
    3131namespace JSC {
    32 
    33 extern const double NaN;
    3432
    3533typedef double (*TranscendentalFunctionPtr)(double);
     
    7775        m_cache = static_cast<CacheEntry*>(fastMalloc(s_cacheSize * sizeof(CacheEntry)));
    7876        for (unsigned x = 0; x < s_cacheSize; ++x) {
    79             m_cache[x].operand = NaN;
    80             m_cache[x].result = NaN;
     77            m_cache[x].operand = std::numeric_limits<double>::quiet_NaN();
     78            m_cache[x].result = std::numeric_limits<double>::quiet_NaN();
    8179        }
    8280    }
  • trunk/Source/JavaScriptCore/runtime/DateConstructor.cpp

    r86730 r88587  
    127127                || (numArgs >= 6 && isnan(doubleArguments[5]))
    128128                || (numArgs >= 7 && isnan(doubleArguments[6])))
    129             value = NaN;
     129            value = std::numeric_limits<double>::quiet_NaN();
    130130        else {
    131131            GregorianDateTime t;
  • trunk/Source/JavaScriptCore/runtime/DateInstanceCache.h

    r62367 r88587  
    3434namespace JSC {
    3535
    36     extern const double NaN;
    37 
    3836    class DateInstanceData : public RefCounted<DateInstanceData> {
    3937    public:
     
    4745    private:
    4846        DateInstanceData()
    49             : m_gregorianDateTimeCachedForMS(NaN)
    50             , m_gregorianDateTimeUTCCachedForMS(NaN)
     47            : m_gregorianDateTimeCachedForMS(std::numeric_limits<double>::quiet_NaN())
     48            , m_gregorianDateTimeUTCCachedForMS(std::numeric_limits<double>::quiet_NaN())
    5149        {
    5250        }
     
    6361        {
    6462            for (size_t i = 0; i < cacheSize; ++i)
    65                 m_cache[i].key = NaN;
     63                m_cache[i].key = std::numeric_limits<double>::quiet_NaN();
    6664        }
    6765       
  • trunk/Source/JavaScriptCore/runtime/JSCell.cpp

    r86499 r88587  
    3030
    3131namespace JSC {
    32 
    33 #if defined NAN && defined INFINITY
    34 
    35 extern const double NaN = NAN;
    36 extern const double Inf = INFINITY;
    37 
    38 #else // !(defined NAN && defined INFINITY)
    39 
    40 // The trick is to define the NaN and Inf globals with a different type than the declaration.
    41 // This trick works because the mangled name of the globals does not include the type, although
    42 // I'm not sure that's guaranteed. There could be alignment issues with this, since arrays of
    43 // characters don't necessarily need the same alignment doubles do, but for now it seems to work.
    44 // It would be good to figure out a 100% clean way that still avoids code that runs at init time.
    45 
    46 // Note, we have to use union to ensure alignment. Otherwise, NaN_Bytes can start anywhere,
    47 // while NaN_double has to be 4-byte aligned for 32-bits.
    48 // With -fstrict-aliasing enabled, unions are the only safe way to do type masquerading.
    49 
    50 static const union {
    51     struct {
    52         unsigned char NaN_Bytes[8];
    53         unsigned char Inf_Bytes[8];
    54     } bytes;
    55    
    56     struct {
    57         double NaN_Double;
    58         double Inf_Double;
    59     } doubles;
    60    
    61 } NaNInf = { {
    62 #if CPU(BIG_ENDIAN)
    63     { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 },
    64     { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 }
    65 #elif CPU(MIDDLE_ENDIAN)
    66     { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 },
    67     { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 }
    68 #else
    69     { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f },
    70     { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }
    71 #endif
    72 } } ;
    73 
    74 extern const double NaN = NaNInf.doubles.NaN_Double;
    75 extern const double Inf = NaNInf.doubles.Inf_Double;
    76  
    77 #endif // !(defined NAN && defined INFINITY)
    7832
    7933const ClassInfo JSCell::s_dummyCellInfo = { "DummyCell", 0, 0, 0 };
  • trunk/Source/JavaScriptCore/runtime/JSCell.h

    r88379 r88587  
    295295        }
    296296        ASSERT(isUndefined());
    297         number = nonInlineNaN();
     297        number = std::numeric_limits<double>::quiet_NaN();
    298298        value = *this;
    299299        return true;
     
    321321        if (isTrue())
    322322            return 1.0;
    323         return isUndefined() ? nonInlineNaN() : 0; // null and false both convert to 0.
     323        return isUndefined() ? std::numeric_limits<double>::quiet_NaN() : 0; // null and false both convert to 0.
    324324    }
    325325
  • trunk/Source/JavaScriptCore/runtime/JSGlobalData.cpp

    r88473 r88587  
    188188    , heap(this)
    189189    , dynamicGlobalObject(0)
    190     , cachedUTCOffset(NaN)
     190    , cachedUTCOffset(std::numeric_limits<double>::quiet_NaN())
    191191    , maxReentryDepth(threadStackType == ThreadStackTypeSmall ? MaxSmallThreadReentryDepth : MaxLargeThreadReentryDepth)
    192192    , m_regExpCache(new RegExpCache(this))
     
    420420void JSGlobalData::resetDateCache()
    421421{
    422     cachedUTCOffset = NaN;
     422    cachedUTCOffset = std::numeric_limits<double>::quiet_NaN();
    423423    dstOffsetCache.reset();
    424424    cachedDateString = UString();
    425     cachedDateStringValue = NaN;
     425    cachedDateStringValue = std::numeric_limits<double>::quiet_NaN();
    426426    dateInstanceCache.reset();
    427427}
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r87346 r88587  
    288288        GlobalPropertyInfo(Identifier(exec, "Math"), new (exec) MathObject(exec, this, MathObject::createStructure(exec->globalData(), m_objectPrototype.get())), DontEnum | DontDelete),
    289289        GlobalPropertyInfo(Identifier(exec, "NaN"), jsNaN(), DontEnum | DontDelete | ReadOnly),
    290         GlobalPropertyInfo(Identifier(exec, "Infinity"), jsNumber(Inf), DontEnum | DontDelete | ReadOnly),
     290        GlobalPropertyInfo(Identifier(exec, "Infinity"), jsNumber(std::numeric_limits<double>::infinity()), DontEnum | DontDelete | ReadOnly),
    291291        GlobalPropertyInfo(Identifier(exec, "undefined"), jsUndefined(), DontEnum | DontDelete | ReadOnly),
    292292        GlobalPropertyInfo(Identifier(exec, "JSON"), new (exec) JSONObject(this, JSONObject::createStructure(exec->globalData(), m_objectPrototype.get())), DontEnum | DontDelete)
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp

    r86727 r88587  
    4949
    5050namespace JSC {
     51
     52#define NaN std::numeric_limits<double>::quiet_NaN()
     53#define Inf std::numeric_limits<double>::infinity()
    5154
    5255static JSValue encode(ExecState* exec, const char* doNotEscape)
     
    473476        if (isfinite(d))
    474477            return JSValue::encode(jsNumber((d > 0) ? floor(d) : ceil(d)));
    475         if (isnan(d) || isinf(d))
    476             return JSValue::encode(jsNaN());
    477         return JSValue::encode(jsNumber(0));
     478        return JSValue::encode(jsNaN());
    478479    }
    479480
     
    494495{
    495496    double n = exec->argument(0).toNumber(exec);
    496     return JSValue::encode(jsBoolean(!isnan(n) && !isinf(n)));
     497    return JSValue::encode(jsBoolean(isfinite(n)));
    497498}
    498499
  • trunk/Source/JavaScriptCore/runtime/JSNotAnObject.cpp

    r82173 r88587  
    5959{
    6060    ASSERT_UNUSED(exec, exec->hadException());
    61     return NaN;
     61    return std::numeric_limits<double>::quiet_NaN();
    6262}
    6363
  • trunk/Source/JavaScriptCore/runtime/JSValue.cpp

    r82173 r88587  
    181181}
    182182
    183 NEVER_INLINE double nonInlineNaN()
    184 {
    185 #if OS(SYMBIAN)
    186     return nanval();
    187 #else
    188     return std::numeric_limits<double>::quiet_NaN();
    189 #endif
    190 }
    191 
    192183bool JSValue::isValidCallee()
    193184{
  • trunk/Source/JavaScriptCore/runtime/JSValue.h

    r84289 r88587  
    3535namespace JSC {
    3636
    37     extern const double NaN;
    38     extern const double Inf;
    39 
    4037    class ExecState;
    4138    class Identifier;
     
    8380#endif
    8481    };
    85 
    86     double nonInlineNaN();
    8782
    8883    // This implements ToInt32, defined in ECMA-262 9.5.
  • trunk/Source/JavaScriptCore/runtime/JSValueInlineMethods.h

    r83517 r88587  
    6868    inline JSValue jsNaN()
    6969    {
    70         return JSValue(nonInlineNaN());
     70        return JSValue(std::numeric_limits<double>::quiet_NaN());
    7171    }
    7272
  • trunk/Source/JavaScriptCore/runtime/MathObject.cpp

    r86727 r88587  
    167167{
    168168    unsigned argsCount = exec->argumentCount();
    169     double result = -Inf;
     169    double result = -std::numeric_limits<double>::infinity();
    170170    for (unsigned k = 0; k < argsCount; ++k) {
    171171        double val = exec->argument(k).toNumber(exec);
    172172        if (isnan(val)) {
    173             result = NaN;
     173            result = std::numeric_limits<double>::quiet_NaN();
    174174            break;
    175175        }
     
    183183{
    184184    unsigned argsCount = exec->argumentCount();
    185     double result = +Inf;
     185    double result = +std::numeric_limits<double>::infinity();
    186186    for (unsigned k = 0; k < argsCount; ++k) {
    187187        double val = exec->argument(k).toNumber(exec);
    188188        if (isnan(val)) {
    189             result = NaN;
     189            result = std::numeric_limits<double>::quiet_NaN();
    190190            break;
    191191        }
  • trunk/Source/JavaScriptCore/runtime/NumberConstructor.cpp

    r86727 r88587  
    8484static JSValue numberConstructorNegInfinity(ExecState*, JSValue, const Identifier&)
    8585{
    86     return jsNumber(-Inf);
     86    return jsNumber(-std::numeric_limits<double>::infinity());
    8787}
    8888
    8989static JSValue numberConstructorPosInfinity(ExecState*, JSValue, const Identifier&)
    9090{
    91     return jsNumber(Inf);
     91    return jsNumber(std::numeric_limits<double>::infinity());
    9292}
    9393
  • trunk/Source/JavaScriptCore/runtime/NumberPrototype.cpp

    r86727 r88587  
    130130
    131131    // Handle NaN and Infinity.
    132     if (isnan(x) || isinf(x))
     132    if (!isfinite(x))
    133133        return JSValue::encode(jsString(exec, UString::number(x)));
    134134
     
    169169    // The check above will return false for NaN or Infinity, these will be
    170170    // handled by numberToString.
    171     ASSERT(!isnan(x) && !isinf(x));
     171    ASSERT(isfinite(x));
    172172
    173173    // Convert to decimal with rounding, and format as decimal.
     
    204204
    205205    // Handle NaN and Infinity.
    206     if (isnan(x) || isinf(x))
     206    if (!isfinite(x))
    207207        return JSValue::encode(jsString(exec, UString::number(x)));
    208208
     
    261261    const char* lastCharInString = s + sizeof(s) - 1;
    262262    double x = v.uncheckedGetNumber();
    263     if (isnan(x) || isinf(x))
     263    if (!isfinite(x))
    264264        return JSValue::encode(jsString(exec, UString::number(x)));
    265265
  • trunk/Source/JavaScriptCore/runtime/UString.cpp

    r75443 r88587  
    5252namespace JSC {
    5353
    54 extern const double NaN;
    55 extern const double Inf;
    56 
    5754COMPILE_ASSERT(sizeof(UString) == sizeof(void*), UString_should_stay_small);
    5855
  • trunk/Source/JavaScriptCore/wtf/DecimalNumber.h

    r70198 r88587  
    4141    DecimalNumber(double d)
    4242    {
    43         ASSERT(!isnan(d) && !isinf(d));
     43        ASSERT(isfinite(d));
    4444        dtoa(m_significand, d, m_sign, m_exponent, m_precision);
    4545
     
    5555    DecimalNumber(double d, RoundingSignificantFiguresType, unsigned significantFigures)
    5656    {
    57         ASSERT(!isnan(d) && !isinf(d));
     57        ASSERT(isfinite(d));
    5858        dtoaRoundSF(m_significand, d, significantFigures, m_sign, m_exponent, m_precision);
    5959
     
    6969    DecimalNumber(double d, RoundingDecimalPlacesType, unsigned decimalPlaces)
    7070    {
    71         ASSERT(!isnan(d) && !isinf(d));
     71        ASSERT(isfinite(d));
    7272        dtoaRoundDP(m_significand, d, decimalPlaces, m_sign, m_exponent, m_precision);
    7373
  • trunk/Source/JavaScriptCore/wtf/dtoa.cpp

    r84466 r88587  
    13181318    ASSERT(!roundingNone || leftright);
    13191319
    1320     ASSERT(!isnan(dd) && !isinf(dd));
     1320    ASSERT(isfinite(dd));
    13211321
    13221322    int bbits, b2, b5, be, dig, i, ieps, ilim = 0, ilim0, ilim1 = 0,
     
    18121812{
    18131813    // Handle NaN and Infinity.
    1814     if (isnan(d) || isinf(d)) {
     1814    if (!isfinite(d)) {
    18151815        if (isnan(d)) {
    18161816            copyAsciiToUTF16(buffer, "NaN", 3);
  • trunk/Source/WebCore/ChangeLog

    r88584 r88587  
     12011-06-10  Gavin Barraclough  <barraclough@apple.com>
     2
     3        Reviewed by Sam Weinig.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=16777
     6        Eliminate JSC::NaN and JSC::Inf
     7
     8        There's no good reason for -K-J-S- JSC to have its own NAN and infinity constants.
     9        The ones in std::numeric_limits are perfectly good.
     10        Remove JSC::Inf, JSC::NaN, switch some cases of (isnan || isinf) to !isfinite.
     11
     12        * bindings/js/JSDataViewCustom.cpp:
     13        (WebCore::getDataViewMember):
     14
    1152011-06-10  James Simonsen  <simonjam@chromium.org>
    216
  • trunk/Source/WebCore/bindings/js/JSDataViewCustom.cpp

    r84194 r88587  
    9090    case AccessDataViewMemberAsFloat64: {
    9191        double value = (type == AccessDataViewMemberAsFloat32) ? imp->getFloat32(byteOffset, littleEndian, ec) : imp->getFloat64(byteOffset, littleEndian, ec);
    92         result = isnan(value) ? JSValue(nonInlineNaN()) : jsNumber(value);
     92        result = isnan(value) ? jsNaN() : jsNumber(value);
    9393        break;
    9494    } default:
Note: See TracChangeset for help on using the changeset viewer.