[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

barraclough at apple.com barraclough at apple.com
Wed Dec 22 12:16:50 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 794f4617fc15515d916ad6cdeff95ed84ccd9fdd
Author: barraclough at apple.com <barraclough at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Aug 18 07:41:22 2010 +0000

    Bug 44146 - Remove toDouble/toUInt32 methods from UString.
    
    Reviewed by Sam Weinig.
    
    JavaScriptCore:
    
    These methods all implement JavaScript language specific behaviour, and as such
    are not suited to being on a generic string object.  They are also inefficient
    and incorrectly used, refactor & cleanup.  Uses of these methods really divide
    out into two cases.
    
    ToNumber:
    Uses of toDouble from JSString and from parseFloat are implementing ecma's
    ToNumber conversion from strings (see ecma-262 9.3.1), so UString::toDouble
    should largely just be moved out to a global jsToNumber function.  ToNumber is
    capable of recognizing either decimal or hexadecimal numbers, but parseFloat
    should only recognize decimal values.  This is currently handled by testing for
    hexadecimal before calling toDouble, which should unnecessary - instead we can
    just split out the two parts to the grammar into separate functions. Also,
    strtod recognizes a set of literals (nan, inf, and infinity - all with any
    capitalization) - which are not defined by any of the specs we are implementing.
    To handle this we need to perform additional work in toDouble to convert the
    unsupported cases of infinities back to NaNs.  Instead we should simply remove
    support for this literals from strtod.  This should provide a more desirable
    behaviour for all clients of strtod.
    
    Indexed properties:
    Uses of the toStrictUInt32 methods are were all converting property names to
    indices, and all uses of toUInt32 were incorrect; in all cases we should have
    been calling toUInt32.  This error results in some incorrect behaviour in the
    DOM (accessing property "0 " of a NodeList should fail; it currently does not).
    Move this method onto Identifier (our canonical property name), and make it
    always perform a strict conversion. Add a layout test to check NodeList does
    convert indexed property names correctly.
    
    * JavaScriptCore.exp:
    * runtime/Arguments.cpp:
    (JSC::Arguments::getOwnPropertySlot):
    (JSC::Arguments::getOwnPropertyDescriptor):
    (JSC::Arguments::put):
    (JSC::Arguments::deleteProperty):
    * runtime/Identifier.cpp:
    (JSC::Identifier::toUInt32):
    * runtime/Identifier.h:
    (JSC::Identifier::toUInt32):
    * runtime/JSArray.cpp:
    (JSC::JSArray::getOwnPropertySlot):
    (JSC::JSArray::getOwnPropertyDescriptor):
    (JSC::JSArray::put):
    (JSC::JSArray::deleteProperty):
    * runtime/JSArray.h:
    (JSC::Identifier::toArrayIndex):
    * runtime/JSByteArray.cpp:
    (JSC::JSByteArray::getOwnPropertySlot):
    (JSC::JSByteArray::getOwnPropertyDescriptor):
    (JSC::JSByteArray::put):
    * runtime/JSGlobalObjectFunctions.cpp:
    (JSC::isInfinity):
    (JSC::jsHexIntegerLiteral):
    (JSC::jsStrDecimalLiteral):
    (JSC::jsToNumber):
    (JSC::parseFloat):
    * runtime/JSGlobalObjectFunctions.h:
    * runtime/JSString.cpp:
    (JSC::JSString::getPrimitiveNumber):
    (JSC::JSString::toNumber):
    (JSC::JSString::getStringPropertyDescriptor):
    * runtime/JSString.h:
    (JSC::JSString::getStringPropertySlot):
    * runtime/ObjectPrototype.cpp:
    (JSC::ObjectPrototype::put):
    * runtime/StringObject.cpp:
    (JSC::StringObject::deleteProperty):
    * runtime/UString.cpp:
    * runtime/UString.h:
    * wtf/dtoa.cpp:
    (WTF::strtod):
    
    WebCore:
    
    These methods all implement JavaScript language specific behaviour, and as such
    are not suited to being on a generic string object.  They are also inefficient
    and incorrectly used, refactor & cleanup.  Uses of these methods really divide
    out into two cases.
    
    ToNumber:
    Uses of toDouble from JSString and from parseFloat are implementing ecma's
    ToNumber conversion from strings (see ecma-262 9.3.1), so UString::toDouble
    should largely just be moved out to a global jsToNumber function.  ToNumber is
    capable of recognizing either decimal or hexadecimal numbers, but parseFloat
    should only recognize decimal values.  This is currently handled by testing for
    hexadecimal before calling toDouble, which should unnecessary - instead we can
    just split out the two parts to the grammar into separate functions. Also,
    strtod recognizes a set of literals (nan, inf, and infinity - all with any
    capitalization) - which are not defined by any of the specs we are implementing.
    To handle this we need to perform additional work in toDouble to convert the
    unsupported cases of infinities back to NaNs.  Instead we should simply remove
    support for this literals from strtod.  This should provide a more desirable
    behaviour for all clients of strtod.
    
    Indexed properties:
    Uses of the toStrictUInt32 methods are were all converting property names to
    indices, and all uses of toUInt32 were incorrect; in all cases we should have
    been calling toUInt32.  This error results in some incorrect behaviour in the
    DOM (accessing property "0 " of a NodeList should fail; it currently does not).
    Move this method onto Identifier (our canonical property name), and make it
    always perform a strict conversion. Add a layout test to check NodeList does
    convert indexed property names correctly.
    
    Test: fast/dom/NodeList/nodelist-item-with-index.html
    
    * WebCore.xcodeproj/project.pbxproj:
    * bindings/js/JSDOMWindowCustom.cpp:
    (WebCore::JSDOMWindow::getOwnPropertySlot):
    (WebCore::JSDOMWindow::getOwnPropertyDescriptor):
    * bindings/js/JSHTMLAllCollectionCustom.cpp:
    (WebCore::callHTMLAllCollection):
    (WebCore::JSHTMLAllCollection::item):
    * bindings/js/JSHTMLCollectionCustom.cpp:
    (WebCore::callHTMLCollection):
    (WebCore::JSHTMLCollection::item):
    * bindings/js/JSNodeListCustom.cpp:
    (WebCore::callNodeList):
    * bindings/scripts/CodeGeneratorJS.pm:
    * bridge/runtime_array.cpp:
    (JSC::RuntimeArray::getOwnPropertySlot):
    (JSC::RuntimeArray::getOwnPropertyDescriptor):
    (JSC::RuntimeArray::put):
    
    LayoutTests:
    
    Test that indexing into nodelists works correctly, particularly
    wrt indices passed as strings that contain whitespace.
    
    * fast/dom/NodeList/nodelist-item-with-index-expected.txt: Added.
    * fast/dom/NodeList/nodelist-item-with-index.html: Added.
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@65588 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 6bfd7c2..d3aa5bb 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -2,6 +2,84 @@
 
         Reviewed by Sam Weinig.
 
+        Bug 44146 - Remove toDouble/toUInt32 methods from UString.
+
+        These methods all implement JavaScript language specific behaviour, and as such
+        are not suited to being on a generic string object.  They are also inefficient
+        and incorrectly used, refactor & cleanup.  Uses of these methods really divide
+        out into two cases.
+
+        ToNumber:
+        Uses of toDouble from JSString and from parseFloat are implementing ecma's
+        ToNumber conversion from strings (see ecma-262 9.3.1), so UString::toDouble
+        should largely just be moved out to a global jsToNumber function.  ToNumber is
+        capable of recognizing either decimal or hexadecimal numbers, but parseFloat
+        should only recognize decimal values.  This is currently handled by testing for
+        hexadecimal before calling toDouble, which should unnecessary - instead we can
+        just split out the two parts to the grammar into separate functions. Also,
+        strtod recognizes a set of literals (nan, inf, and infinity - all with any
+        capitalization) - which are not defined by any of the specs we are implementing.
+        To handle this we need to perform additional work in toDouble to convert the
+        unsupported cases of infinities back to NaNs.  Instead we should simply remove
+        support for this literals from strtod.  This should provide a more desirable
+        behaviour for all clients of strtod.
+
+        Indexed properties:
+        Uses of the toStrictUInt32 methods are were all converting property names to
+        indices, and all uses of toUInt32 were incorrect; in all cases we should have
+        been calling toUInt32.  This error results in some incorrect behaviour in the
+        DOM (accessing property "0 " of a NodeList should fail; it currently does not).
+        Move this method onto Identifier (our canonical property name), and make it
+        always perform a strict conversion. Add a layout test to check NodeList does
+        convert indexed property names correctly.
+
+        * JavaScriptCore.exp:
+        * runtime/Arguments.cpp:
+        (JSC::Arguments::getOwnPropertySlot):
+        (JSC::Arguments::getOwnPropertyDescriptor):
+        (JSC::Arguments::put):
+        (JSC::Arguments::deleteProperty):
+        * runtime/Identifier.cpp:
+        (JSC::Identifier::toUInt32):
+        * runtime/Identifier.h:
+        (JSC::Identifier::toUInt32):
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::getOwnPropertySlot):
+        (JSC::JSArray::getOwnPropertyDescriptor):
+        (JSC::JSArray::put):
+        (JSC::JSArray::deleteProperty):
+        * runtime/JSArray.h:
+        (JSC::Identifier::toArrayIndex):
+        * runtime/JSByteArray.cpp:
+        (JSC::JSByteArray::getOwnPropertySlot):
+        (JSC::JSByteArray::getOwnPropertyDescriptor):
+        (JSC::JSByteArray::put):
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::isInfinity):
+        (JSC::jsHexIntegerLiteral):
+        (JSC::jsStrDecimalLiteral):
+        (JSC::jsToNumber):
+        (JSC::parseFloat):
+        * runtime/JSGlobalObjectFunctions.h:
+        * runtime/JSString.cpp:
+        (JSC::JSString::getPrimitiveNumber):
+        (JSC::JSString::toNumber):
+        (JSC::JSString::getStringPropertyDescriptor):
+        * runtime/JSString.h:
+        (JSC::JSString::getStringPropertySlot):
+        * runtime/ObjectPrototype.cpp:
+        (JSC::ObjectPrototype::put):
+        * runtime/StringObject.cpp:
+        (JSC::StringObject::deleteProperty):
+        * runtime/UString.cpp:
+        * runtime/UString.h:
+        * wtf/dtoa.cpp:
+        (WTF::strtod):
+
+2010-08-17  Gavin Barraclough  <barraclough at apple.com>
+
+        Reviewed by Sam Weinig.
+
         Bug 44099 - REGRESSION(r65468): Crashes in StringImpl::find
 
         Bug 44080 introuduced a couple of cases in which array bounds could be overrun.
diff --git a/JavaScriptCore/JavaScriptCore.exp b/JavaScriptCore/JavaScriptCore.exp
index ffd1b93..5652d0f 100644
--- a/JavaScriptCore/JavaScriptCore.exp
+++ b/JavaScriptCore/JavaScriptCore.exp
@@ -107,6 +107,7 @@ __ZN3JSC10Identifier3addEPNS_9ExecStateEPKc
 __ZN3JSC10Identifier4fromEPNS_9ExecStateEi
 __ZN3JSC10Identifier4fromEPNS_9ExecStateEj
 __ZN3JSC10Identifier5equalEPKN3WTF10StringImplEPKc
+__ZN3JSC10Identifier8toUInt32ERKNS_7UStringERb
 __ZN3JSC10JSFunction4infoE
 __ZN3JSC10JSFunction4nameEPNS_9ExecStateE
 __ZN3JSC10throwErrorEPNS_9ExecStateENS_7JSValueE
@@ -515,12 +516,9 @@ __ZNK3JSC7JSValue16toObjectSlowCaseEPNS_9ExecStateE
 __ZNK3JSC7JSValue19synthesizePrototypeEPNS_9ExecStateE
 __ZNK3JSC7JSValue20toThisObjectSlowCaseEPNS_9ExecStateE
 __ZNK3JSC7JSValue9toIntegerEPNS_9ExecStateE
-__ZNK3JSC7UString14toStrictUInt32EPb
 __ZNK3JSC7UString4utf8Eb
 __ZNK3JSC7UString5asciiEv
 __ZNK3JSC7UString6substrEjj
-__ZNK3JSC7UString8toUInt32EPb
-__ZNK3JSC7UString8toUInt32EPbb
 __ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateERKNS_10IdentifierE
 __ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateEj
 __ZNK3JSC8JSObject12defaultValueEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
diff --git a/JavaScriptCore/jit/JITStubs.cpp b/JavaScriptCore/jit/JITStubs.cpp
index 8052d2c..e9ba25d 100644
--- a/JavaScriptCore/jit/JITStubs.cpp
+++ b/JavaScriptCore/jit/JITStubs.cpp
@@ -45,6 +45,7 @@
 #include "JSArray.h"
 #include "JSByteArray.h"
 #include "JSFunction.h"
+#include "JSGlobalObjectFunctions.h"
 #include "JSNotAnObject.h"
 #include "JSPropertyNameIterator.h"
 #include "JSStaticScopeObject.h"
@@ -2814,16 +2815,16 @@ DEFINE_STUB_FUNCTION(int, op_eq)
 
     if (cell1->isString()) {
         if (src2.isInt32())
-            return static_cast<JSString*>(cell1)->value(stackFrame.callFrame).toDouble() == src2.asInt32();
+            return jsToNumber(static_cast<JSString*>(cell1)->value(stackFrame.callFrame)) == src2.asInt32();
             
         if (src2.isDouble())
-            return static_cast<JSString*>(cell1)->value(stackFrame.callFrame).toDouble() == src2.asDouble();
+            return jsToNumber(static_cast<JSString*>(cell1)->value(stackFrame.callFrame)) == src2.asDouble();
 
         if (src2.isTrue())
-            return static_cast<JSString*>(cell1)->value(stackFrame.callFrame).toDouble() == 1.0;
+            return jsToNumber(static_cast<JSString*>(cell1)->value(stackFrame.callFrame)) == 1.0;
 
         if (src2.isFalse())
-            return static_cast<JSString*>(cell1)->value(stackFrame.callFrame).toDouble() == 0.0;
+            return jsToNumber(static_cast<JSString*>(cell1)->value(stackFrame.callFrame)) == 0.0;
 
         JSCell* cell2 = asCell(src2);
         if (cell2->isString())
diff --git a/JavaScriptCore/runtime/Arguments.cpp b/JavaScriptCore/runtime/Arguments.cpp
index 4ca0328..450dc7d 100644
--- a/JavaScriptCore/runtime/Arguments.cpp
+++ b/JavaScriptCore/runtime/Arguments.cpp
@@ -157,7 +157,7 @@ bool Arguments::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& sl
 bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
 {
     bool isArrayIndex;
-    unsigned i = toArrayIndex(propertyName.ustring(), &isArrayIndex);
+    unsigned i = propertyName.toArrayIndex(isArrayIndex);
     if (isArrayIndex && i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
         if (i < d->numParameters) {
             slot.setRegisterSlot(&d->registers[d->firstParameterIndex + i]);
@@ -182,7 +182,7 @@ bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyNa
 bool Arguments::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
 {
     bool isArrayIndex;
-    unsigned i = toArrayIndex(propertyName.ustring(), &isArrayIndex);
+    unsigned i = propertyName.toArrayIndex(isArrayIndex);
     if (isArrayIndex && i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
         if (i < d->numParameters) {
             descriptor.setDescriptor(d->registers[d->firstParameterIndex + i].jsValue(), DontEnum);
@@ -233,7 +233,7 @@ void Arguments::put(ExecState* exec, unsigned i, JSValue value, PutPropertySlot&
 void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
 {
     bool isArrayIndex;
-    unsigned i = toArrayIndex(propertyName.ustring(), &isArrayIndex);
+    unsigned i = propertyName.toArrayIndex(isArrayIndex);
     if (isArrayIndex && i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
         if (i < d->numParameters)
             d->registers[d->firstParameterIndex + i] = JSValue(value);
@@ -276,7 +276,7 @@ bool Arguments::deleteProperty(ExecState* exec, unsigned i)
 bool Arguments::deleteProperty(ExecState* exec, const Identifier& propertyName) 
 {
     bool isArrayIndex;
-    unsigned i = toArrayIndex(propertyName.ustring(), &isArrayIndex);
+    unsigned i = propertyName.toArrayIndex(isArrayIndex);
     if (isArrayIndex && i < d->numArguments) {
         if (!d->deletedArguments) {
             d->deletedArguments.set(new bool[d->numArguments]);
diff --git a/JavaScriptCore/runtime/Identifier.cpp b/JavaScriptCore/runtime/Identifier.cpp
index 472af70..d375eff 100644
--- a/JavaScriptCore/runtime/Identifier.cpp
+++ b/JavaScriptCore/runtime/Identifier.cpp
@@ -168,6 +168,49 @@ struct IdentifierUCharBufferTranslator {
     }
 };
 
+uint32_t Identifier::toUInt32(const UString& string, bool& ok)
+{
+    ok = false;
+
+    unsigned length = string.length();
+    const UChar* characters = string.characters();
+
+    // An empty string is not a number.
+    if (!length)
+        return 0;
+
+    // Get the first character, turning it into a digit.
+    uint32_t value = characters[0] - '0';
+    if (value > 9)
+        return 0;
+
+    // Check for leading zeros. If the first characher is 0, then the
+    // length of the string must be one - e.g. "042" is not equal to "42".
+    if (!value && length > 1)
+        return 0;
+
+    while (--length) {
+        // Multiply value by 10, checking for overflow out of 32 bits.
+        if (value > 0xFFFFFFFFU / 10)
+            return 0;
+        value *= 10;
+
+        // Get the next character, turning it into a digit.
+        uint32_t newValue = *(++characters) - '0';
+        if (newValue > 9)
+            return 0;
+
+        // Add in the old value, checking for overflow out of 32 bits.
+        newValue += value;
+        if (newValue < value)
+            return 0;
+        value = newValue;
+    }
+
+    ok = true;
+    return value;
+}
+
 PassRefPtr<StringImpl> Identifier::add(JSGlobalData* globalData, const UChar* s, int length)
 {
     if (length == 1) {
diff --git a/JavaScriptCore/runtime/Identifier.h b/JavaScriptCore/runtime/Identifier.h
index 04dffdf..3a8aed7 100644
--- a/JavaScriptCore/runtime/Identifier.h
+++ b/JavaScriptCore/runtime/Identifier.h
@@ -59,15 +59,14 @@ namespace JSC {
         static Identifier from(JSGlobalData*, unsigned y);
         static Identifier from(JSGlobalData*, int y);
         static Identifier from(JSGlobalData*, double y);
-        
+
+        static uint32_t toUInt32(const UString&, bool& ok);
+        uint32_t toUInt32(bool& ok) const { return toUInt32(m_string, ok); }
+        unsigned toArrayIndex(bool& ok) const;
+
         bool isNull() const { return m_string.isNull(); }
         bool isEmpty() const { return m_string.isEmpty(); }
         
-        uint32_t toUInt32(bool* ok) const { return m_string.toUInt32(ok); }
-        uint32_t toUInt32(bool* ok, bool tolerateEmptyString) const { return m_string.toUInt32(ok, tolerateEmptyString); };
-        uint32_t toStrictUInt32(bool* ok) const { return m_string.toStrictUInt32(ok); }
-        double toDouble() const { return m_string.toDouble(); }
-        
         friend bool operator==(const Identifier&, const Identifier&);
         friend bool operator!=(const Identifier&, const Identifier&);
 
diff --git a/JavaScriptCore/runtime/JSArray.cpp b/JavaScriptCore/runtime/JSArray.cpp
index a0c46da..9c3570b 100644
--- a/JavaScriptCore/runtime/JSArray.cpp
+++ b/JavaScriptCore/runtime/JSArray.cpp
@@ -273,7 +273,7 @@ bool JSArray::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName
     }
 
     bool isArrayIndex;
-    unsigned i = toArrayIndex(propertyName.ustring(), &isArrayIndex);
+    unsigned i = propertyName.toArrayIndex(isArrayIndex);
     if (isArrayIndex)
         return JSArray::getOwnPropertySlot(exec, i, slot);
 
@@ -290,7 +290,7 @@ bool JSArray::getOwnPropertyDescriptor(ExecState* exec, const Identifier& proper
     ArrayStorage* storage = m_storage;
     
     bool isArrayIndex;
-    unsigned i = toArrayIndex(propertyName.ustring(), &isArrayIndex);
+    unsigned i = propertyName.toArrayIndex(isArrayIndex);
     if (isArrayIndex) {
         if (i >= storage->m_length)
             return false;
@@ -317,7 +317,7 @@ bool JSArray::getOwnPropertyDescriptor(ExecState* exec, const Identifier& proper
 void JSArray::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
 {
     bool isArrayIndex;
-    unsigned i = toArrayIndex(propertyName.ustring(), &isArrayIndex);
+    unsigned i = propertyName.toArrayIndex(isArrayIndex);
     if (isArrayIndex) {
         put(exec, i, value);
         return;
@@ -475,7 +475,7 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu
 bool JSArray::deleteProperty(ExecState* exec, const Identifier& propertyName)
 {
     bool isArrayIndex;
-    unsigned i = toArrayIndex(propertyName.ustring(), &isArrayIndex);
+    unsigned i = propertyName.toArrayIndex(isArrayIndex);
     if (isArrayIndex)
         return deleteProperty(exec, i);
 
diff --git a/JavaScriptCore/runtime/JSArray.h b/JavaScriptCore/runtime/JSArray.h
index b72a285..9e155d8 100644
--- a/JavaScriptCore/runtime/JSArray.h
+++ b/JavaScriptCore/runtime/JSArray.h
@@ -264,11 +264,11 @@ namespace JSC {
 
     // Rule from ECMA 15.2 about what an array index is.
     // Must exactly match string form of an unsigned integer, and be less than 2^32 - 1.
-    inline unsigned toArrayIndex(const UString& string, bool* ok)
+    inline unsigned Identifier::toArrayIndex(bool& ok) const
     {
-        unsigned i = string.toStrictUInt32(ok);
+        unsigned i = toUInt32(ok);
         if (ok && i >= 0xFFFFFFFFU)
-            *ok = false;
+            ok = false;
         return i;
     }
 
diff --git a/JavaScriptCore/runtime/JSByteArray.cpp b/JavaScriptCore/runtime/JSByteArray.cpp
index 803a08c..88519cf 100644
--- a/JavaScriptCore/runtime/JSByteArray.cpp
+++ b/JavaScriptCore/runtime/JSByteArray.cpp
@@ -60,7 +60,7 @@ PassRefPtr<Structure> JSByteArray::createStructure(JSValue prototype)
 bool JSByteArray::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
 {
     bool ok;
-    unsigned index = propertyName.toUInt32(&ok, false);
+    unsigned index = propertyName.toUInt32(ok);
     if (ok && canAccessIndex(index)) {
         slot.setValue(getIndex(exec, index));
         return true;
@@ -71,7 +71,7 @@ bool JSByteArray::getOwnPropertySlot(ExecState* exec, const Identifier& property
 bool JSByteArray::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
 {
     bool ok;
-    unsigned index = propertyName.toUInt32(&ok, false);
+    unsigned index = propertyName.toUInt32(ok);
     if (ok && canAccessIndex(index)) {
         descriptor.setDescriptor(getIndex(exec, index), DontDelete);
         return true;
@@ -91,7 +91,7 @@ bool JSByteArray::getOwnPropertySlot(ExecState* exec, unsigned propertyName, Pro
 void JSByteArray::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
 {
     bool ok;
-    unsigned index = propertyName.toUInt32(&ok, false);
+    unsigned index = propertyName.toUInt32(ok);
     if (ok) {
         setIndex(exec, index, value);
         return;
diff --git a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
index e72d342..4f4276a 100644
--- a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
+++ b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
@@ -276,23 +276,161 @@ static double parseInt(const UString& s, int radix)
     return sign * number;
 }
 
+static const int SizeOfInfinity = 8;
+
+static bool isInfinity(const UChar* data, const UChar* end)
+{
+    return (end - data) >= SizeOfInfinity
+        && data[0] == 'I'
+        && data[1] == 'n'
+        && data[2] == 'f'
+        && data[3] == 'i'
+        && data[4] == 'n'
+        && data[5] == 'i'
+        && data[6] == 't'
+        && data[7] == 'y';
+}
+
+// See ecma-262 9.3.1
+static double jsHexIntegerLiteral(const UChar*& data, const UChar* end)
+{
+    // Hex number.
+    data += 2;
+    const UChar* firstDigitPosition = data;
+    double number = 0;
+    while (true) {
+        number = number * 16 + toASCIIHexValue(*data);
+        ++data;
+        if (data == end)
+            break;
+        if (!isASCIIHexDigit(*data))
+            break;
+    }
+    if (number >= mantissaOverflowLowerBound)
+        number = parseIntOverflow(firstDigitPosition, data - firstDigitPosition, 16);
+
+    return number;
+}
+
+// See ecma-262 9.3.1
+static double jsStrDecimalLiteral(const UChar*& data, const UChar* end)
+{
+    ASSERT(data < end);
+
+    // Copy the sting into a null-terminated byte buffer, and call strtod.
+    Vector<char, 32> byteBuffer;
+    for (const UChar* characters = data; characters < end; ++characters) {
+        UChar character = *characters;
+        byteBuffer.append(isASCII(character) ? character : 0);
+    }
+    byteBuffer.append(0);
+    char* endOfNumber;
+    double number = WTF::strtod(byteBuffer.data(), &endOfNumber);
+
+    // Check if strtod found a number; if so return it.
+    ptrdiff_t consumed = endOfNumber - byteBuffer.data();
+    if (consumed) {
+        data += consumed;
+        return number;
+    }
+
+    // Check for [+-]?Infinity
+    switch (*data) {
+    case 'I':
+        if (isInfinity(data, end)) {
+            data += SizeOfInfinity;
+            return Inf;
+        }
+        break;
+
+    case '+':
+        if (isInfinity(data + 1, end)) {
+            data += SizeOfInfinity + 1;
+            return Inf;
+        }
+        break;
+
+    case '-':
+        if (isInfinity(data + 1, end)) {
+            data += SizeOfInfinity + 1;
+            return -Inf;
+        }
+        break;
+    }
+
+    // Not a number.
+    return NaN;
+}
+
+// See ecma-262 9.3.1
+double jsToNumber(const UString& s)
+{
+    unsigned size = s.length();
+
+    if (size == 1) {
+        UChar c = s.characters()[0];
+        if (isASCIIDigit(c))
+            return c - '0';
+        if (isStrWhiteSpace(c))
+            return 0;
+        return NaN;
+    }
+
+    const UChar* data = s.characters();
+    const UChar* end = data + size;
+
+    // Skip leading white space.
+    for (; data < end; ++data) {
+        if (!isStrWhiteSpace(*data))
+            break;
+    }
+
+    // Empty string.
+    if (data == end)
+        return 0.0;
+
+    double number;
+    if (data[0] == '0' && data + 2 < end && (data[1] | 0x20) == 'x' && isASCIIHexDigit(data[2]))
+        number = jsHexIntegerLiteral(data, end);
+    else
+        number = jsStrDecimalLiteral(data, end);
+
+    // Allow trailing white space.
+    for (; data < end; ++data) {
+        if (!isStrWhiteSpace(*data))
+            break;
+    }
+    if (data != end)
+        return NaN;
+
+    return number;
+}
+
 static double parseFloat(const UString& s)
 {
-    // Check for 0x prefix here, because toDouble allows it, but we must treat it as 0.
-    // Need to skip any whitespace and then one + or - sign.
-    int length = s.length();
+    unsigned size = s.length();
+
+    if (size == 1) {
+        UChar c = s.characters()[0];
+        if (isASCIIDigit(c))
+            return c - '0';
+        return NaN;
+    }
+
     const UChar* data = s.characters();
-    int p = 0;
-    while (p < length && isStrWhiteSpace(data[p]))
-        ++p;
+    const UChar* end = data + size;
 
-    if (p < length && (data[p] == '+' || data[p] == '-'))
-        ++p;
+    // Skip leading white space.
+    for (; data < end; ++data) {
+        if (!isStrWhiteSpace(*data))
+            break;
+    }
 
-    if (length - p >= 2 && data[p] == '0' && (data[p + 1] == 'x' || data[p + 1] == 'X'))
-        return 0;
+    // Empty string.
+    if (data == end)
+        return NaN;
 
-    return s.toDouble(true /*tolerant*/, false /* NaN for empty string */);
+    return jsStrDecimalLiteral(data, end);
 }
 
 EncodedJSValue JSC_HOST_CALL globalFuncEval(ExecState* exec)
diff --git a/JavaScriptCore/runtime/JSGlobalObjectFunctions.h b/JavaScriptCore/runtime/JSGlobalObjectFunctions.h
index e634fae..6dc7343 100644
--- a/JavaScriptCore/runtime/JSGlobalObjectFunctions.h
+++ b/JavaScriptCore/runtime/JSGlobalObjectFunctions.h
@@ -55,6 +55,7 @@ namespace JSC {
     double parseIntOverflow(const char*, int length, int radix);
     double parseIntOverflow(const UChar*, int length, int radix);
     bool isStrWhiteSpace(UChar);
+    double jsToNumber(const UString& s);
 
 } // namespace JSC
 
diff --git a/JavaScriptCore/runtime/JSString.cpp b/JavaScriptCore/runtime/JSString.cpp
index 99e49b6..0ed02df 100644
--- a/JavaScriptCore/runtime/JSString.cpp
+++ b/JavaScriptCore/runtime/JSString.cpp
@@ -24,6 +24,7 @@
 #include "JSString.h"
 
 #include "JSGlobalObject.h"
+#include "JSGlobalObjectFunctions.h"
 #include "JSObject.h"
 #include "Operations.h"
 #include "StringObject.h"
@@ -177,7 +178,7 @@ JSValue JSString::toPrimitive(ExecState*, PreferredPrimitiveType) const
 bool JSString::getPrimitiveNumber(ExecState* exec, double& number, JSValue& result)
 {
     result = this;
-    number = value(exec).toDouble();
+    number = jsToNumber(value(exec));
     return false;
 }
 
@@ -188,7 +189,7 @@ bool JSString::toBoolean(ExecState*) const
 
 double JSString::toNumber(ExecState* exec) const
 {
-    return value(exec).toDouble();
+    return jsToNumber(value(exec));
 }
 
 UString JSString::toString(ExecState* exec) const
@@ -240,7 +241,7 @@ bool JSString::getStringPropertyDescriptor(ExecState* exec, const Identifier& pr
     }
     
     bool isStrictUInt32;
-    unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
+    unsigned i = propertyName.toUInt32(isStrictUInt32);
     if (isStrictUInt32 && i < m_length) {
         descriptor.setDescriptor(getIndex(exec, i), DontDelete | ReadOnly);
         return true;
diff --git a/JavaScriptCore/runtime/JSString.h b/JavaScriptCore/runtime/JSString.h
index 898201d..12ced10 100644
--- a/JavaScriptCore/runtime/JSString.h
+++ b/JavaScriptCore/runtime/JSString.h
@@ -564,7 +564,7 @@ namespace JSC {
         }
 
         bool isStrictUInt32;
-        unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
+        unsigned i = propertyName.toUInt32(isStrictUInt32);
         if (isStrictUInt32 && i < m_length) {
             slot.setValue(getIndex(exec, i));
             return true;
diff --git a/JavaScriptCore/runtime/ObjectPrototype.cpp b/JavaScriptCore/runtime/ObjectPrototype.cpp
index 6197f75..57a8a31 100644
--- a/JavaScriptCore/runtime/ObjectPrototype.cpp
+++ b/JavaScriptCore/runtime/ObjectPrototype.cpp
@@ -65,7 +65,7 @@ void ObjectPrototype::put(ExecState* exec, const Identifier& propertyName, JSVal
 
     if (m_hasNoPropertiesWithUInt32Names) {
         bool isUInt32;
-        propertyName.toStrictUInt32(&isUInt32);
+        propertyName.toUInt32(isUInt32);
         m_hasNoPropertiesWithUInt32Names = !isUInt32;
     }
 }
diff --git a/JavaScriptCore/runtime/StringObject.cpp b/JavaScriptCore/runtime/StringObject.cpp
index c8cac35..dc27618 100644
--- a/JavaScriptCore/runtime/StringObject.cpp
+++ b/JavaScriptCore/runtime/StringObject.cpp
@@ -80,7 +80,7 @@ bool StringObject::deleteProperty(ExecState* exec, const Identifier& propertyNam
     if (propertyName == exec->propertyNames().length)
         return false;
     bool isStrictUInt32;
-    unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
+    unsigned i = propertyName.toUInt32(isStrictUInt32);
     if (isStrictUInt32 && internalValue()->canGetIndex(i))
         return false;
     return JSObject::deleteProperty(exec, propertyName);
diff --git a/JavaScriptCore/runtime/UString.cpp b/JavaScriptCore/runtime/UString.cpp
index 78f82a5..225cf28 100644
--- a/JavaScriptCore/runtime/UString.cpp
+++ b/JavaScriptCore/runtime/UString.cpp
@@ -204,215 +204,6 @@ UString UString::number(double d)
     return UString(buffer, length);
 }
 
-static inline bool isInfinity(double number)
-{
-    return number == Inf || number == -Inf;
-}
-
-static bool isInfinity(const UChar* data, const UChar* end)
-{
-    return data + 7 < end
-        && data[0] == 'I'
-        && data[1] == 'n'
-        && data[2] == 'f'
-        && data[3] == 'i'
-        && data[4] == 'n'
-        && data[5] == 'i'
-        && data[6] == 't'
-        && data[7] == 'y';
-}
-
-double UString::toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) const
-{
-    unsigned size = this->length();
-
-    if (size == 1) {
-        UChar c = characters()[0];
-        if (isASCIIDigit(c))
-            return c - '0';
-        if (isStrWhiteSpace(c) && tolerateEmptyString)
-            return 0;
-        return NaN;
-    }
-
-    const UChar* data = this->characters();
-    const UChar* end = data + size;
-
-    // Skip leading white space.
-    for (; data < end; ++data) {
-        if (!isStrWhiteSpace(*data))
-            break;
-    }
-
-    // Empty string.
-    if (data == end)
-        return tolerateEmptyString ? 0.0 : NaN;
-
-    double number;
-
-    if (data[0] == '0' && data + 2 < end && (data[1] | 0x20) == 'x' && isASCIIHexDigit(data[2])) {
-        // Hex number.
-        data += 2;
-        const UChar* firstDigitPosition = data;
-        number = 0;
-        while (true) {
-            number = number * 16 + toASCIIHexValue(*data);
-            ++data;
-            if (data == end)
-                break;
-            if (!isASCIIHexDigit(*data))
-                break;
-        }
-        if (number >= mantissaOverflowLowerBound)
-            number = parseIntOverflow(firstDigitPosition, data - firstDigitPosition, 16);
-    } else {
-        // Decimal number.
-
-        // Put into a null-terminated byte buffer.
-        Vector<char, 32> byteBuffer;
-        for (const UChar* characters = data; characters < end; ++characters) {
-            UChar character = *characters;
-            byteBuffer.append(isASCII(character) ? character : 0);
-        }
-        byteBuffer.append(0);
-
-        char* byteBufferEnd;
-        number = WTF::strtod(byteBuffer.data(), &byteBufferEnd);
-        const UChar* pastNumber = data + (byteBufferEnd - byteBuffer.data());
-
-        if ((number || pastNumber != data) && !isInfinity(number))
-            data = pastNumber;
-        else {
-            // We used strtod() to do the conversion. However, strtod() handles
-            // infinite values slightly differently than JavaScript in that it
-            // converts the string "inf" with any capitalization to infinity,
-            // whereas the ECMA spec requires that it be converted to NaN.
-
-            double signedInfinity = Inf;
-            if (data < end) {
-                if (*data == '+')
-                    data++;
-                else if (*data == '-') {
-                    signedInfinity = -Inf;
-                    data++;
-                }
-            }
-            if (isInfinity(data, end)) {
-                number = signedInfinity;
-                data += 8;
-            } else if (isInfinity(number) && data < end && (*data | 0x20) != 'i')
-                data = pastNumber;
-            else
-                return NaN;
-        }
-    }
-
-    // Look for trailing junk.
-    if (!tolerateTrailingJunk) {
-        // Allow trailing white space.
-        for (; data < end; ++data) {
-            if (!isStrWhiteSpace(*data))
-                break;
-        }
-        if (data != end)
-            return NaN;
-    }
-
-    return number;
-}
-
-double UString::toDouble(bool tolerateTrailingJunk) const
-{
-    return toDouble(tolerateTrailingJunk, true);
-}
-
-double UString::toDouble() const
-{
-    return toDouble(false, true);
-}
-
-uint32_t UString::toUInt32(bool* ok) const
-{
-    double d = toDouble();
-    bool b = true;
-
-    if (d != static_cast<uint32_t>(d)) {
-        b = false;
-        d = 0;
-    }
-
-    if (ok)
-        *ok = b;
-
-    return static_cast<uint32_t>(d);
-}
-
-uint32_t UString::toUInt32(bool* ok, bool tolerateEmptyString) const
-{
-    double d = toDouble(false, tolerateEmptyString);
-    bool b = true;
-
-    if (d != static_cast<uint32_t>(d)) {
-        b = false;
-        d = 0;
-    }
-
-    if (ok)
-        *ok = b;
-
-    return static_cast<uint32_t>(d);
-}
-
-uint32_t UString::toStrictUInt32(bool* ok) const
-{
-    if (ok)
-        *ok = false;
-
-    // Empty string is not OK.
-    unsigned len = m_impl->length();
-    if (len == 0)
-        return 0;
-    const UChar* p = m_impl->characters();
-    unsigned short c = p[0];
-
-    // If the first digit is 0, only 0 itself is OK.
-    if (c == '0') {
-        if (len == 1 && ok)
-            *ok = true;
-        return 0;
-    }
-
-    // Convert to UInt32, checking for overflow.
-    uint32_t i = 0;
-    while (1) {
-        // Process character, turning it into a digit.
-        if (c < '0' || c > '9')
-            return 0;
-        const unsigned d = c - '0';
-
-        // Multiply by 10, checking for overflow out of 32 bits.
-        if (i > 0xFFFFFFFFU / 10)
-            return 0;
-        i *= 10;
-
-        // Add in the digit, checking for overflow out of 32 bits.
-        const unsigned max = 0xFFFFFFFFU - d;
-        if (i > max)
-            return 0;
-        i += d;
-
-        // Handle end of string.
-        if (--len == 0) {
-            if (ok)
-                *ok = true;
-            return i;
-        }
-
-        // Get next character.
-        c = *(++p);
-    }
-}
-
 UString UString::substr(unsigned pos, unsigned len) const
 {
     // FIXME: We used to check against a limit of Heap::minExtraCost / sizeof(UChar).
diff --git a/JavaScriptCore/runtime/UString.h b/JavaScriptCore/runtime/UString.h
index 6567299..7f2e08e 100644
--- a/JavaScriptCore/runtime/UString.h
+++ b/JavaScriptCore/runtime/UString.h
@@ -107,14 +107,6 @@ public:
     size_t reverseFind(const UString& str, unsigned start = UINT_MAX) const
         { return m_impl ? m_impl->reverseFind(str.impl(), start) : notFound; }
 
-    double toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) const;
-    double toDouble(bool tolerateTrailingJunk) const;
-    double toDouble() const;
-
-    uint32_t toUInt32(bool* ok = 0) const;
-    uint32_t toUInt32(bool* ok, bool tolerateEmptyString) const;
-    uint32_t toStrictUInt32(bool* ok = 0) const;
-
     UString substr(unsigned pos = 0, unsigned len = UINT_MAX) const;
 
 private:
diff --git a/JavaScriptCore/wtf/dtoa.cpp b/JavaScriptCore/wtf/dtoa.cpp
index 2c478a0..f7e19bf 100644
--- a/JavaScriptCore/wtf/dtoa.cpp
+++ b/JavaScriptCore/wtf/dtoa.cpp
@@ -88,21 +88,6 @@
  * #define Bad_float_h if your system lacks a float.h or if it does not
  *    define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
  *    FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
- * #define INFNAN_CHECK on IEEE systems to cause strtod to check for
- *    Infinity and NaN (case insensitively).  On some systems (e.g.,
- *    some HP systems), it may be necessary to #define NAN_WORD0
- *    appropriately -- to the most significant word of a quiet NaN.
- *    (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.)
- *    When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined,
- *    strtod also accepts (case insensitively) strings of the form
- *    NaN(x), where x is a string of hexadecimal digits and spaces;
- *    if there is only one string of hexadecimal digits, it is taken
- *    for the 52 fraction bits of the resulting NaN; if there are two
- *    or more strings of hex digits, the first is for the high 20 bits,
- *    the second and subsequent for the low 32 bits, with intervening
- *    white space ignored; but if this results in none of the 52
- *    fraction bits being on (an IEEE Infinity symbol), then NAN_WORD0
- *    and NAN_WORD1 are used instead.
  * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that
  *    avoids underflows on inputs whose result does not underflow.
  *    If you #define NO_IEEE_Scale on a machine that uses IEEE-format
@@ -166,9 +151,6 @@
 #define IEEE_8087
 #endif
 
-#define INFNAN_CHECK
-#define No_Hex_NaN
-
 #if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(IEEE_ARM) != 1
 Exactly one of IEEE_8087, IEEE_ARM or IEEE_MC68k should be defined.
 #endif
@@ -1040,78 +1022,6 @@ static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
 #define Scale_Bit 0x10
 #define n_bigtens 5
 
-#if defined(INFNAN_CHECK)
-
-#ifndef NAN_WORD0
-#define NAN_WORD0 0x7ff80000
-#endif
-
-#ifndef NAN_WORD1
-#define NAN_WORD1 0
-#endif
-
-static int match(const char** sp, const char* t)
-{
-    int c, d;
-    const char* s = *sp;
-
-    while ((d = *t++)) {
-        if ((c = *++s) >= 'A' && c <= 'Z')
-            c += 'a' - 'A';
-        if (c != d)
-            return 0;
-    }
-    *sp = s + 1;
-    return 1;
-}
-
-#ifndef No_Hex_NaN
-static void hexnan(U* rvp, const char** sp)
-{
-    uint32_t c, x[2];
-    const char* s;
-    int havedig, udx0, xshift;
-
-    x[0] = x[1] = 0;
-    havedig = xshift = 0;
-    udx0 = 1;
-    s = *sp;
-    while ((c = *(const unsigned char*)++s)) {
-        if (c >= '0' && c <= '9')
-            c -= '0';
-        else if (c >= 'a' && c <= 'f')
-            c += 10 - 'a';
-        else if (c >= 'A' && c <= 'F')
-            c += 10 - 'A';
-        else if (c <= ' ') {
-            if (udx0 && havedig) {
-                udx0 = 0;
-                xshift = 1;
-            }
-            continue;
-        } else if (/*(*/ c == ')' && havedig) {
-            *sp = s + 1;
-            break;
-        } else
-            return;    /* invalid form: don't change *sp */
-        havedig = 1;
-        if (xshift) {
-            xshift = 0;
-            x[0] = x[1];
-            x[1] = 0;
-        }
-        if (udx0)
-            x[0] = (x[0] << 4) | (x[1] >> 28);
-        x[1] = (x[1] << 4) | c;
-    }
-    if ((x[0] &= 0xfffff) || x[1]) {
-        word0(rvp) = Exp_mask | x[0];
-        word1(rvp) = x[1];
-    }
-}
-#endif /*No_Hex_NaN*/
-#endif /* INFNAN_CHECK */
-
 double strtod(const char* s00, char** se)
 {
 #ifdef Avoid_Underflow
@@ -1236,33 +1146,6 @@ digDone:
     }
     if (!nd) {
         if (!nz && !nz0) {
-#ifdef INFNAN_CHECK
-            /* Check for Nan and Infinity */
-            switch (c) {
-            case 'i':
-            case 'I':
-                if (match(&s, "nf")) {
-                    --s;
-                    if (!match(&s, "inity"))
-                        ++s;
-                    word0(&rv) = 0x7ff00000;
-                    word1(&rv) = 0;
-                    goto ret;
-                }
-                break;
-            case 'n':
-            case 'N':
-                if (match(&s, "an")) {
-                    word0(&rv) = NAN_WORD0;
-                    word1(&rv) = NAN_WORD1;
-#ifndef No_Hex_NaN
-                    if (*s == '(') /*)*/
-                        hexnan(&rv, &s);
-#endif
-                    goto ret;
-                }
-            }
-#endif /* INFNAN_CHECK */
 ret0:
             s = s00;
             sign = 0;
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 7741b72..dca4cd1 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,15 @@
+2010-08-17  Gavin Barraclough  <barraclough at apple.com>
+
+        Reviewed by Sam Weinig.
+
+        Bug 44146 - Remove toDouble/toUInt32 methods from UString.
+
+        Test that indexing into nodelists works correctly, particularly
+        wrt indices passed as strings that contain whitespace.
+
+        * fast/dom/NodeList/nodelist-item-with-index-expected.txt: Added.
+        * fast/dom/NodeList/nodelist-item-with-index.html: Added.
+
 2010-08-17  Ademar de Souza Reis Jr  <ademar.reis at openbossa.org>
 
         Reviewed by Daniel Bates.
diff --git a/LayoutTests/fast/dom/NodeList/nodelist-item-with-index-expected.txt b/LayoutTests/fast/dom/NodeList/nodelist-item-with-index-expected.txt
new file mode 100644
index 0000000..1c4040d
--- /dev/null
+++ b/LayoutTests/fast/dom/NodeList/nodelist-item-with-index-expected.txt
@@ -0,0 +1,18 @@
+This tests that items in a NodeList can be retrieved by index.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+text1
+text2
+
+PASS div0 == div0s is true
+PASS div0 == div0s_ is false
+PASS div0 == div1 is false
+PASS div0s == div0s_ is false
+PASS div0s == div1 is false
+PASS div0s_ == div1 is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/dom/NodeList/nodelist-item-with-index.html b/LayoutTests/fast/dom/NodeList/nodelist-item-with-index.html
new file mode 100644
index 0000000..369e021
--- /dev/null
+++ b/LayoutTests/fast/dom/NodeList/nodelist-item-with-index.html
@@ -0,0 +1,38 @@
+<html>
+<head>
+<link rel="stylesheet" href="../../js/resources/js-test-style.css">
+<script src="../../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id='div1'>text1</div>
+<div id='div2'>text2</div><br>
+
+<div id="console"></div>
+
+<script>
+description('This tests that items in a NodeList can be retrieved by index.');
+
+var nodeList = document.getElementsByTagName('div');
+var div0 = nodeList[0];
+var div0s = nodeList["0"];
+var div0s_ = nodeList["0 "];
+var div1 = nodeList["1"];
+
+// Getting properties 0 and "0" should get the same thing, but getting
+// properties "0 " and 1 should get different items.  "0 " should not
+// be converted to 0, so should be undefined, and the item at index
+// 1 should be defined (since there are at least two divs on the page),
+// but should be a different div to the one at index 0.
+shouldBeTrue("div0 == div0s");
+shouldBeFalse("div0 == div0s_");
+shouldBeFalse("div0 == div1");
+shouldBeFalse("div0s == div0s_");
+shouldBeFalse("div0s == div1");
+shouldBeFalse("div0s_ == div1");
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 2af29cd..d5aa474 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,58 @@
+2010-08-17  Gavin Barraclough  <barraclough at apple.com>
+
+        Reviewed by Sam Weinig.
+
+        Bug 44146 - Remove toDouble/toUInt32 methods from UString.
+
+        These methods all implement JavaScript language specific behaviour, and as such
+        are not suited to being on a generic string object.  They are also inefficient
+        and incorrectly used, refactor & cleanup.  Uses of these methods really divide
+        out into two cases.
+
+        ToNumber:
+        Uses of toDouble from JSString and from parseFloat are implementing ecma's
+        ToNumber conversion from strings (see ecma-262 9.3.1), so UString::toDouble
+        should largely just be moved out to a global jsToNumber function.  ToNumber is
+        capable of recognizing either decimal or hexadecimal numbers, but parseFloat
+        should only recognize decimal values.  This is currently handled by testing for
+        hexadecimal before calling toDouble, which should unnecessary - instead we can
+        just split out the two parts to the grammar into separate functions. Also,
+        strtod recognizes a set of literals (nan, inf, and infinity - all with any
+        capitalization) - which are not defined by any of the specs we are implementing.
+        To handle this we need to perform additional work in toDouble to convert the
+        unsupported cases of infinities back to NaNs.  Instead we should simply remove
+        support for this literals from strtod.  This should provide a more desirable
+        behaviour for all clients of strtod.
+
+        Indexed properties:
+        Uses of the toStrictUInt32 methods are were all converting property names to
+        indices, and all uses of toUInt32 were incorrect; in all cases we should have
+        been calling toUInt32.  This error results in some incorrect behaviour in the
+        DOM (accessing property "0 " of a NodeList should fail; it currently does not).
+        Move this method onto Identifier (our canonical property name), and make it
+        always perform a strict conversion. Add a layout test to check NodeList does
+        convert indexed property names correctly.
+
+        Test: fast/dom/NodeList/nodelist-item-with-index.html
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * bindings/js/JSDOMWindowCustom.cpp:
+        (WebCore::JSDOMWindow::getOwnPropertySlot):
+        (WebCore::JSDOMWindow::getOwnPropertyDescriptor):
+        * bindings/js/JSHTMLAllCollectionCustom.cpp:
+        (WebCore::callHTMLAllCollection):
+        (WebCore::JSHTMLAllCollection::item):
+        * bindings/js/JSHTMLCollectionCustom.cpp:
+        (WebCore::callHTMLCollection):
+        (WebCore::JSHTMLCollection::item):
+        * bindings/js/JSNodeListCustom.cpp:
+        (WebCore::callNodeList):
+        * bindings/scripts/CodeGeneratorJS.pm:
+        * bridge/runtime_array.cpp:
+        (JSC::RuntimeArray::getOwnPropertySlot):
+        (JSC::RuntimeArray::getOwnPropertyDescriptor):
+        (JSC::RuntimeArray::put):
+
 2010-08-18  Adam Barth  <abarth at webkit.org>
 
         Reviewed by Adele Peterson.
diff --git a/WebCore/WebCore.xcodeproj/project.pbxproj b/WebCore/WebCore.xcodeproj/project.pbxproj
index bf2e250..58a26f2 100644
--- a/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -20372,6 +20372,7 @@
 			isa = PBXProject;
 			buildConfigurationList = 149C284308902B11008A9EFC /* Build configuration list for PBXProject "WebCore" */;
 			compatibilityVersion = "Xcode 2.4";
+			developmentRegion = English;
 			hasScannedForEncodings = 1;
 			knownRegions = (
 				English,
diff --git a/WebCore/bindings/js/JSDOMWindowCustom.cpp b/WebCore/bindings/js/JSDOMWindowCustom.cpp
index fc57f31..2ad71f0 100644
--- a/WebCore/bindings/js/JSDOMWindowCustom.cpp
+++ b/WebCore/bindings/js/JSDOMWindowCustom.cpp
@@ -271,7 +271,7 @@ bool JSDOMWindow::getOwnPropertySlot(ExecState* exec, const Identifier& property
 
     // allow window[1] or parent[1] etc. (#56983)
     bool ok;
-    unsigned i = toArrayIndex(propertyName.ustring(), &ok);
+    unsigned i = propertyName.toArrayIndex(ok);
     if (ok && i < impl()->frame()->tree()->childCount()) {
         slot.setCustomIndex(this, i, indexGetter);
         return true;
@@ -345,7 +345,7 @@ bool JSDOMWindow::getOwnPropertyDescriptor(ExecState* exec, const Identifier& pr
     }
     
     bool ok;
-    unsigned i = toArrayIndex(propertyName.ustring(), &ok);
+    unsigned i = propertyName.toArrayIndex(ok);
     if (ok && i < impl()->frame()->tree()->childCount()) {
         PropertySlot slot;
         slot.setCustomIndex(this, i, indexGetter);
diff --git a/WebCore/bindings/js/JSHTMLAllCollectionCustom.cpp b/WebCore/bindings/js/JSHTMLAllCollectionCustom.cpp
index 559efe5..64615b9 100644
--- a/WebCore/bindings/js/JSHTMLAllCollectionCustom.cpp
+++ b/WebCore/bindings/js/JSHTMLAllCollectionCustom.cpp
@@ -74,7 +74,7 @@ static EncodedJSValue JSC_HOST_CALL callHTMLAllCollection(ExecState* exec)
         // Support for document.all(<index>) etc.
         bool ok;
         UString string = exec->argument(0).toString(exec);
-        unsigned index = string.toUInt32(&ok, false);
+        unsigned index = Identifier::toUInt32(string, ok);
         if (ok)
             return JSValue::encode(toJS(exec, jsCollection->globalObject(), collection->item(index)));
 
@@ -85,7 +85,7 @@ static EncodedJSValue JSC_HOST_CALL callHTMLAllCollection(ExecState* exec)
     // The second arg, if set, is the index of the item we want
     bool ok;
     UString string = exec->argument(0).toString(exec);
-    unsigned index = exec->argument(1).toString(exec).toUInt32(&ok, false);
+    unsigned index = Identifier::toUInt32(exec->argument(1).toString(exec), ok);
     if (ok) {
         String pstr = ustringToString(string);
         Node* node = collection->namedItem(pstr);
@@ -122,7 +122,7 @@ JSValue JSHTMLAllCollection::nameGetter(ExecState* exec, JSValue slotBase, const
 JSValue JSHTMLAllCollection::item(ExecState* exec)
 {
     bool ok;
-    uint32_t index = exec->argument(0).toString(exec).toUInt32(&ok, false);
+    uint32_t index = Identifier::toUInt32(exec->argument(0).toString(exec), ok);
     if (ok)
         return toJS(exec, globalObject(), impl()->item(index));
     return getNamedItems(exec, this, Identifier(exec, exec->argument(0).toString(exec)));
diff --git a/WebCore/bindings/js/JSHTMLCollectionCustom.cpp b/WebCore/bindings/js/JSHTMLCollectionCustom.cpp
index 7602e2e..6b2f350 100644
--- a/WebCore/bindings/js/JSHTMLCollectionCustom.cpp
+++ b/WebCore/bindings/js/JSHTMLCollectionCustom.cpp
@@ -70,7 +70,7 @@ static EncodedJSValue JSC_HOST_CALL callHTMLCollection(ExecState* exec)
         // Support for document.all(<index>) etc.
         bool ok;
         UString string = exec->argument(0).toString(exec);
-        unsigned index = string.toUInt32(&ok, false);
+        unsigned index = Identifier::toUInt32(string, ok);
         if (ok)
             return JSValue::encode(toJS(exec, jsCollection->globalObject(), collection->item(index)));
 
@@ -81,7 +81,7 @@ static EncodedJSValue JSC_HOST_CALL callHTMLCollection(ExecState* exec)
     // The second arg, if set, is the index of the item we want
     bool ok;
     UString string = exec->argument(0).toString(exec);
-    unsigned index = exec->argument(1).toString(exec).toUInt32(&ok, false);
+    unsigned index = Identifier::toUInt32(exec->argument(1).toString(exec), ok);
     if (ok) {
         String pstr = ustringToString(string);
         Node* node = collection->namedItem(pstr);
@@ -118,7 +118,7 @@ JSValue JSHTMLCollection::nameGetter(ExecState* exec, JSValue slotBase, const Id
 JSValue JSHTMLCollection::item(ExecState* exec)
 {
     bool ok;
-    uint32_t index = exec->argument(0).toString(exec).toUInt32(&ok, false);
+    uint32_t index = Identifier::toUInt32(exec->argument(0).toString(exec), ok);
     if (ok)
         return toJS(exec, globalObject(), impl()->item(index));
     return getNamedItems(exec, this, Identifier(exec, exec->argument(0).toString(exec)));
diff --git a/WebCore/bindings/js/JSNodeListCustom.cpp b/WebCore/bindings/js/JSNodeListCustom.cpp
index 27162ea..c81914c 100644
--- a/WebCore/bindings/js/JSNodeListCustom.cpp
+++ b/WebCore/bindings/js/JSNodeListCustom.cpp
@@ -39,7 +39,7 @@ namespace WebCore {
 static EncodedJSValue JSC_HOST_CALL callNodeList(ExecState* exec)
 {
     bool ok;
-    unsigned index = exec->argument(0).toString(exec).toUInt32(&ok);
+    unsigned index = Identifier::toUInt32(exec->argument(0).toString(exec), ok);
     if (!ok)
         return JSValue::encode(jsUndefined());
     return JSValue::encode(toJS(exec, static_cast<JSNodeList*>(exec->callee())->impl()->item(index)));
diff --git a/WebCore/bindings/scripts/CodeGeneratorJS.pm b/WebCore/bindings/scripts/CodeGeneratorJS.pm
index f48159b..0b18d95 100644
--- a/WebCore/bindings/scripts/CodeGeneratorJS.pm
+++ b/WebCore/bindings/scripts/CodeGeneratorJS.pm
@@ -426,7 +426,7 @@ sub GenerateGetOwnPropertySlotBody
 
     if ($dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"} || $dataNode->extendedAttributes->{"HasNumericIndexGetter"}) {
         push(@getOwnPropertySlotImpl, "    bool ok;\n");
-        push(@getOwnPropertySlotImpl, "    unsigned index = propertyName.toUInt32(&ok, false);\n");
+        push(@getOwnPropertySlotImpl, "    unsigned index = propertyName.toUInt32(ok);\n");
 
         # If the item function returns a string then we let the ConvertNullStringTo handle the cases
         # where the index is out of range.
@@ -520,7 +520,7 @@ sub GenerateGetOwnPropertyDescriptorBody
     
     if ($dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"} || $dataNode->extendedAttributes->{"HasNumericIndexGetter"}) {
         push(@getOwnPropertyDescriptorImpl, "    bool ok;\n");
-        push(@getOwnPropertyDescriptorImpl, "    unsigned index = propertyName.toUInt32(&ok, false);\n");
+        push(@getOwnPropertyDescriptorImpl, "    unsigned index = propertyName.toUInt32(ok);\n");
         push(@getOwnPropertyDescriptorImpl, "    if (ok && index < static_cast<$implClassName*>(impl())->length()) {\n");
         if ($dataNode->extendedAttributes->{"HasCustomIndexGetter"} || $dataNode->extendedAttributes->{"HasNumericIndexGetter"}) {
             # Assume that if there's a setter, the index will be writable
@@ -1648,7 +1648,7 @@ sub GenerateImplementation
                 push(@implContent, "{\n");
                 if ($dataNode->extendedAttributes->{"HasCustomIndexSetter"}) {
                     push(@implContent, "    bool ok;\n");
-                    push(@implContent, "    unsigned index = propertyName.toUInt32(&ok, false);\n");
+                    push(@implContent, "    unsigned index = propertyName.toUInt32(ok);\n");
                     push(@implContent, "    if (ok) {\n");
                     push(@implContent, "        indexSetter(exec, index, value);\n");
                     push(@implContent, "        return;\n");
diff --git a/WebCore/bridge/runtime_array.cpp b/WebCore/bridge/runtime_array.cpp
index 41627b8..ca12f48 100644
--- a/WebCore/bridge/runtime_array.cpp
+++ b/WebCore/bridge/runtime_array.cpp
@@ -82,7 +82,7 @@ bool RuntimeArray::getOwnPropertySlot(ExecState* exec, const Identifier& propert
     }
     
     bool ok;
-    unsigned index = toArrayIndex(propertyName.ustring(), &ok);
+    unsigned index = propertyName.toArrayIndex(ok);
     if (ok) {
         if (index < getLength()) {
             slot.setCustomIndex(this, index, indexGetter);
@@ -103,7 +103,7 @@ bool RuntimeArray::getOwnPropertyDescriptor(ExecState* exec, const Identifier& p
     }
     
     bool ok;
-    unsigned index = toArrayIndex(propertyName.ustring(), &ok);
+    unsigned index = propertyName.toArrayIndex(ok);
     if (ok) {
         if (index < getLength()) {
             PropertySlot slot;
@@ -134,7 +134,7 @@ void RuntimeArray::put(ExecState* exec, const Identifier& propertyName, JSValue
     }
     
     bool ok;
-    unsigned index = toArrayIndex(propertyName.ustring(), &ok);
+    unsigned index = propertyName.toArrayIndex(ok);
     if (ok) {
         getConcreteArray()->setValueAt(exec, index, value);
         return;

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list