source: webkit/trunk/JavaScriptCore/runtime/JSByteArray.cpp@ 67583

Last change on this file since 67583 was 65588, checked in by [email protected], 15 years ago

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.

(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.
File size: 3.9 KB
Line 
1/*
2 * Copyright (C) 2009 Apple Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "JSByteArray.h"
28
29#include "JSGlobalObject.h"
30#include "PropertyNameArray.h"
31
32using namespace WTF;
33
34namespace JSC {
35
36const ClassInfo JSByteArray::s_defaultInfo = { "ByteArray", 0, 0, 0 };
37
38JSByteArray::JSByteArray(ExecState* exec, NonNullPassRefPtr<Structure> structure, ByteArray* storage, const JSC::ClassInfo* classInfo)
39 : JSObject(structure)
40 , m_storage(storage)
41 , m_classInfo(classInfo)
42{
43 putDirect(exec->globalData().propertyNames->length, jsNumber(exec, m_storage->length()), ReadOnly | DontDelete);
44}
45
46#if !ASSERT_DISABLED
47JSByteArray::~JSByteArray()
48{
49 ASSERT(vptr() == JSGlobalData::jsByteArrayVPtr);
50}
51#endif
52
53
54PassRefPtr<Structure> JSByteArray::createStructure(JSValue prototype)
55{
56 PassRefPtr<Structure> result = Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount);
57 return result;
58}
59
60bool JSByteArray::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
61{
62 bool ok;
63 unsigned index = propertyName.toUInt32(ok);
64 if (ok && canAccessIndex(index)) {
65 slot.setValue(getIndex(exec, index));
66 return true;
67 }
68 return JSObject::getOwnPropertySlot(exec, propertyName, slot);
69}
70
71bool JSByteArray::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
72{
73 bool ok;
74 unsigned index = propertyName.toUInt32(ok);
75 if (ok && canAccessIndex(index)) {
76 descriptor.setDescriptor(getIndex(exec, index), DontDelete);
77 return true;
78 }
79 return JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor);
80}
81
82bool JSByteArray::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
83{
84 if (canAccessIndex(propertyName)) {
85 slot.setValue(getIndex(exec, propertyName));
86 return true;
87 }
88 return JSObject::getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot);
89}
90
91void JSByteArray::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
92{
93 bool ok;
94 unsigned index = propertyName.toUInt32(ok);
95 if (ok) {
96 setIndex(exec, index, value);
97 return;
98 }
99 JSObject::put(exec, propertyName, value, slot);
100}
101
102void JSByteArray::put(ExecState* exec, unsigned propertyName, JSValue value)
103{
104 setIndex(exec, propertyName, value);
105}
106
107void JSByteArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
108{
109 unsigned length = m_storage->length();
110 for (unsigned i = 0; i < length; ++i)
111 propertyNames.add(Identifier::from(exec, i));
112 JSObject::getOwnPropertyNames(exec, propertyNames, mode);
113}
114
115}
116
Note: See TracBrowser for help on using the repository browser.