Ignore:
Timestamp:
Sep 19, 2010, 6:23:33 PM (15 years ago)
Author:
[email protected]
Message:

Bug 46065 - Unify implementation of ToInt32 and ToUInt32, don't use fmod.

Reviewed by Oliver Hunt.

These methods implement the same conversion (see discussion in the notes
of sections of 9.5 and 9.6 of the spec), only differing in how the result
is interpretted.

JavaScriptCore:

Date prototype is incorrectly using toInt32, and this is causing us to
provide an output value indicating whether the input to ToInt32 was finite
(the corresponding methods on Date are actually spec'ed to use ToInteger,
not ToInt32). This patch partially fixes this in order to remove this
bogus output value, hoewever more work will be require to bring Date
fully up to spec compliance (the constructor is still performing ToInt32
conversions).

(JSC::fillStructuresUsingTimeArgs):
(JSC::fillStructuresUsingDateArgs):
(JSC::dateProtoFuncSetYear):

  • runtime/JSValue.cpp:

(JSC::toInt32):

  • runtime/JSValue.h:

(JSC::toUInt32):
(JSC::JSValue::toInt32):
(JSC::JSValue::toUInt32):

WebCore:

Removing JSValue::toInt32 (since this has weird, non-spec function).
A couple of places in the binding are using this method, so adding
finiteInt32Value to the bindings to maintain current behaviour.

Test: fast/js/toInt32UInt32.html

  • bindings/js/JSDOMBinding.h:

(WebCore::finiteInt32Value):

  • bindings/js/JSHTMLOptionsCollectionCustom.cpp:

(WebCore::JSHTMLOptionsCollection::add):

  • bindings/js/JSSQLResultSetRowListCustom.cpp:

(WebCore::JSSQLResultSetRowList::item):

  • bindings/js/JSSVGPODListCustom.h:

(WebCore::JSSVGPODListCustom::getItem):
(WebCore::JSSVGPODListCustom::insertItemBefore):
(WebCore::JSSVGPODListCustom::replaceItem):
(WebCore::JSSVGPODListCustom::removeItem):

  • bindings/js/JSSVGPathSegListCustom.cpp:

(WebCore::JSSVGPathSegList::getItem):
(WebCore::JSSVGPathSegList::insertItemBefore):
(WebCore::JSSVGPathSegList::replaceItem):
(WebCore::JSSVGPathSegList::removeItem):

LayoutTests:

Add test cases for ToInt32 / ToUInt32 functionality.

  • fast/js/script-tests/toInt32UInt32.js: Added.
  • fast/js/toInt32UInt32-expected.txt: Added.
  • fast/js/toInt32UInt32.html: Added.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/runtime/JSValue.h

    r66318 r67825  
    5757
    5858    double nonInlineNaN();
    59     int32_t toInt32SlowCase(double, bool& ok);
    60     uint32_t toUInt32SlowCase(double, bool& ok);
     59
     60    // This implements ToInt32, defined in ECMA-262 9.5.
     61    int32_t toInt32(double);
     62
     63    // This implements ToUInt32, defined in ECMA-262 9.6.
     64    inline uint32_t toUInt32(double number)
     65    {
     66        // As commented in the spec, the operation of ToInt32 and ToUint32 only differ
     67        // in how the result is interpreted; see NOTEs in sections 9.5 and 9.6.
     68        return toInt32(number);
     69    }
    6170
    6271    class JSValue {
     
    164173        double toIntegerPreserveNaN(ExecState*) const;
    165174        int32_t toInt32(ExecState*) const;
    166         int32_t toInt32(ExecState*, bool& ok) const;
    167175        uint32_t toUInt32(ExecState*) const;
    168         uint32_t toUInt32(ExecState*, bool& ok) const;
    169176
    170177#if ENABLE(JSC_ZOMBIES)
     
    368375    inline bool operator!=(const JSCell* a, const JSValue b) { return JSValue(a) != b; }
    369376
    370     inline int32_t toInt32(double val)
    371     {
    372         if (!(val >= -2147483648.0 && val < 2147483648.0)) {
    373             bool ignored;
    374             return toInt32SlowCase(val, ignored);
    375         }
    376         return static_cast<int32_t>(val);
    377     }
    378 
    379     inline uint32_t toUInt32(double val)
    380     {
    381         if (!(val >= 0.0 && val < 4294967296.0)) {
    382             bool ignored;
    383             return toUInt32SlowCase(val, ignored);
    384         }
    385         return static_cast<uint32_t>(val);
    386     }
    387 
    388377    // FIXME: We should deprecate this and just use JSValue::asCell() instead.
    389378    JSCell* asCell(JSValue);
     
    398387        if (isInt32())
    399388            return asInt32();
    400 
    401         double val = toNumber(exec);
    402 
    403         if (val >= -2147483648.0 && val < 2147483648.0)
    404             return static_cast<int32_t>(val);
    405 
    406         bool ignored;
    407         return toInt32SlowCase(val, ignored);
     389        return JSC::toInt32(toNumber(exec));
    408390    }
    409391
    410392    inline uint32_t JSValue::toUInt32(ExecState* exec) const
    411393    {
    412         if (isUInt32())
    413             return asUInt32();
    414 
    415         double val = toNumber(exec);
    416 
    417         if (val >= 0.0 && val < 4294967296.0)
    418             return static_cast<uint32_t>(val);
    419 
    420         bool ignored;
    421         return toUInt32SlowCase(val, ignored);
    422     }
    423 
    424     inline int32_t JSValue::toInt32(ExecState* exec, bool& ok) const
    425     {
    426         if (isInt32()) {
    427             ok = true;
    428             return asInt32();
    429         }
    430 
    431         double val = toNumber(exec);
    432 
    433         if (val >= -2147483648.0 && val < 2147483648.0) {
    434             ok = true;
    435             return static_cast<int32_t>(val);
    436         }
    437 
    438         return toInt32SlowCase(val, ok);
    439     }
    440 
    441     inline uint32_t JSValue::toUInt32(ExecState* exec, bool& ok) const
    442     {
    443         if (isUInt32()) {
    444             ok = true;
    445             return asInt32();
    446         }
    447 
    448         double val = toNumber(exec);
    449 
    450         if (val >= 0.0 && val < 4294967296.0) {
    451             ok = true;
    452             return static_cast<uint32_t>(val);
    453         }
    454 
    455         return toUInt32SlowCase(val, ok);
     394        // See comment on JSC::toUInt32, above.
     395        return toInt32(exec);
    456396    }
    457397
Note: See TracChangeset for help on using the changeset viewer.