Commit ebd6d4e5 authored by dsmith's avatar dsmith

JavaScriptCore:

        Reviewed by Darin.

        http://bugs.webkit.org/show_bug.cgi?id=12963
        Fix some inconsistencies in the Mozilla JS Array extras implementations
        with respect to the Mozilla implementation:

          - holes in arrays should be skipped, not treated as undefined,
            by all such methods
          - an element with value undefined is not a hole
          - Array.prototype.forEach should return undefined

        * kjs/array_object.cpp:
        (ArrayInstance::getOwnPropertySlot):
        (ArrayProtoFunc::callAsFunction):

LayoutTests:

        Reviewed by Darin.

         http://bugs.webkit.org/show_bug.cgi?id=12963
         Fix some inconsistencies in the Mozilla JS Array extras implementations
         with respect to the Mozilla implementation:

           - holes in arrays should be skipped, not treated as undefined,
             by all such methods
           - an element with value undefined is not a hole
           - Array.prototype.forEach should return undefined

        * fast/js/array-every-expected.txt:
        * fast/js/array-filter-expected.txt: Added.
        * fast/js/array-filter.html: Added.
        * fast/js/array-foreach-expected.txt:
        * fast/js/array-foreach.html:
        * fast/js/array-indexof-expected.txt:
        * fast/js/array-indexof.html:
        * fast/js/array-lastIndexOf-expected.txt:
        * fast/js/array-map-expected.txt: Added.
        * fast/js/array-map.html: Added.
        * fast/js/array-some-expected.txt:
        * fast/js/array-some.html:
        * fast/js/resources/array-every.js:
        * fast/js/resources/array-lastIndexOf.js:



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@20569 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 06d89a01
2007-03-28 Jeff Walden <jwalden+code@mit.edu>
Reviewed by Darin.
http://bugs.webkit.org/show_bug.cgi?id=12963
Fix some inconsistencies in the Mozilla JS Array extras implementations
with respect to the Mozilla implementation:
- holes in arrays should be skipped, not treated as undefined,
by all such methods
- an element with value undefined is not a hole
- Array.prototype.forEach should return undefined
* kjs/array_object.cpp:
(ArrayInstance::getOwnPropertySlot):
(ArrayProtoFunc::callAsFunction):
2007-03-27 Anders Carlsson <acarlsson@apple.com>
Reviewed by Geoff.
......
......@@ -101,7 +101,7 @@ bool ArrayInstance::getOwnPropertySlot(ExecState* exec, const Identifier& proper
return false;
if (index < storageLength) {
JSValue *v = storage[index];
if (!v || v->isUndefined())
if (!v)
return false;
slot.setValueSlot(this, &storage[index]);
return true;
......@@ -120,7 +120,7 @@ bool ArrayInstance::getOwnPropertySlot(ExecState *exec, unsigned index, Property
return false;
if (index < storageLength) {
JSValue *v = storage[index];
if (!v || v->isUndefined())
if (!v)
return false;
slot.setValueSlot(this, &storage[index]);
return true;
......@@ -789,7 +789,7 @@ JSValue* ArrayProtoFunc::callAsFunction(ExecState* exec, JSObject* thisObj, cons
if (id == Filter)
resultArray = static_cast<JSObject *>(exec->lexicalInterpreter()->builtinArray()->construct(exec, List::empty()));
else {
else {
List args;
args.append(jsNumber(length));
resultArray = static_cast<JSObject *>(exec->lexicalInterpreter()->builtinArray()->construct(exec, args));
......@@ -838,7 +838,7 @@ JSValue* ArrayProtoFunc::callAsFunction(ExecState* exec, JSObject* thisObj, cons
if (id == Some || id == Every)
result = jsBoolean(id == Every);
else
result = thisObj;
result = jsUndefined();
for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
PropertySlot slot;
......@@ -885,7 +885,7 @@ JSValue* ArrayProtoFunc::callAsFunction(ExecState* exec, JSObject* thisObj, cons
for (; index < length; ++index) {
JSValue* e = getProperty(exec, thisObj, index);
if (!e)
e = jsUndefined();
continue;
if (strictEqual(exec, searchElement, e))
return jsNumber(index);
}
......@@ -911,7 +911,7 @@ JSValue* ArrayProtoFunc::callAsFunction(ExecState* exec, JSObject* thisObj, cons
for (; index >= 0; --index) {
JSValue* e = getProperty(exec, thisObj, index);
if (!e)
e = jsUndefined();
continue;
if (strictEqual(exec, searchElement, e))
return jsNumber(index);
}
......
2007-03-28 Jeff Walden <jwalden+code@mit.edu>
Reviewed by Darin.
http://bugs.webkit.org/show_bug.cgi?id=12963
Fix some inconsistencies in the Mozilla JS Array extras implementations
with respect to the Mozilla implementation:
- holes in arrays should be skipped, not treated as undefined,
by all such methods
- an element with value undefined is not a hole
- Array.prototype.forEach should return undefined
* fast/js/array-every-expected.txt:
* fast/js/array-filter-expected.txt: Added.
* fast/js/array-filter.html: Added.
* fast/js/array-foreach-expected.txt:
* fast/js/array-foreach.html:
* fast/js/array-indexof-expected.txt:
* fast/js/array-indexof.html:
* fast/js/array-lastIndexOf-expected.txt:
* fast/js/array-map-expected.txt: Added.
* fast/js/array-map.html: Added.
* fast/js/array-some-expected.txt:
* fast/js/array-some.html:
* fast/js/resources/array-every.js:
* fast/js/resources/array-lastIndexOf.js:
2007-03-28 Maciej Stachowiak <mjs@apple.com>
Reviewed by Darin.
......@@ -42,6 +42,10 @@ PASS [12, 5, 8, 130, 44].every(isBigEnoughShortCircuit) is false
PASS accumulator.toString() is [12, 5].toString()
PASS [12, 54, 18, 130, 44].every(isBigEnoughShortCircuit) is true
PASS accumulator.toString() is [12, 54, 18, 130, 44].toString()
7.0 Behavior for Holes in Arrays
PASS arr.every(isNotUndefined) is true
PASS arr.every(isNotUndefined) is true
PASS successfullyParsed is true
TEST COMPLETE
......
1.0 Behavior with Holes in Array
The following tests ensure that filter skips holes in the array it constructs. You should see true printed twice:
true
true
<html>
<head>
<script type="text/javascript">
function print(str) {
document.writeln(str+"<br/>");
}
if (window.layoutTestController)
layoutTestController.dumpAsText();
</script>
</head>
<body>
1.0 Behavior with Holes in Array<br/>
The following tests ensure that filter skips holes in the array it constructs. You should see true printed twice:<br/><br/>
<script>
function passUndefined(element, index, array) {
return typeof element === "undefined";
}
var arr = [undefined];
var res = arr.filter(passUndefined);
print(res.length == 1 && 0 in res && res[0] === undefined);
arr = new Array(20);
res = arr.filter(passUndefined);
print(res.length == 0);
</script>
</body>
</html>
......@@ -51,3 +51,14 @@ TypeError: Type error
TypeError: Type error
TypeError: Type error
6.0 Behavior for Holes in Arrays
This test checks that holes in arrays (indexes which have been deleted or are not present) are not included in enumeration:
Manually deleted index not enumerated
Array created using constructor has no properties, so no indexes enumerated
7.0 Return Value
This test checks that the return value of Array.prototype.forEach is undefined:
Return value is undefined!
......@@ -139,5 +139,43 @@ try {
</script>
<br/>
6.0 Behavior for Holes in Arrays<br/>
This test checks that holes in arrays (indexes which have been deleted or are not present) are not included in enumeration:<br/><br/>
<script>
function throwIfUndefined(element, index, array) {
if (typeof element === "undefined")
throw "undefined element enumerated!";
}
var arr;
try {
arr = [5, 5, 5, 5];
delete arr[1];
arr.forEach(throwIfUndefined);
print("Manually deleted index not enumerated");
} catch (e) {
print(e);
}
try {
arr = new Array(20);
arr.forEach(throwIfUndefined);
print("Array created using constructor has no properties, so no indexes enumerated");
} catch (e) {
print(e);
}
</script>
<br/>
7.0 Return Value<br/>
This test checks that the return value of Array.prototype.forEach is undefined:<br/><br/>
<script>
var wasUndefined = typeof ([1, 2, 3].forEach(function(){})) === "undefined";
print("Return value is " + (wasUndefined ? "" : "NOT ") + "undefined!");
</script>
</body>
</html>
\ No newline at end of file
</html>
......@@ -49,6 +49,9 @@
13.0 Looking for undefined
* The indexOf undefined is 7
* The indexOf undefined is -1
* The indexOf undefined is 3
* The indexOf undefined is -1
* The indexOf undefined is -1
14.0 Object using the Array prototype
* The indexOf String "Hello" is 0
......
......@@ -14,6 +14,11 @@ testArray3[3] = 5;
testArray3[4] = 5;
testArray3[5] = 9;
testArray3.length = 6;
var testArray4 = [5, 5, 5, undefined];
delete testArray4[1];
var testArray5 = [5, 5, 5, undefined];
delete testArray5[3];
var testArray6 = new Array(20);
if (window.layoutTestController)
layoutTestController.dumpAsText();
......@@ -23,76 +28,79 @@ if (window.layoutTestController)
<body>
<p>1.0 Direct Testing, no starting at Parameter<br>
* The indexOf String "Hello" is <script>document.write(testArray.indexOf("Hello"))</script><br>
* The indexOf String "Hi" is <script>document.write(testArray.indexOf("Hi"))</script><br>
* The indexOf Boolean 'true' is <script>document.write(testArray.indexOf( true ))</script><br>
* The indexOf Number '5' is <script>document.write(testArray.indexOf( 5 ))</script><br>
* The indexOf Number '9' is <script>document.write(testArray.indexOf( 9 ))</script>
* The indexOf String "Hello" is <script>document.write(testArray.indexOf("Hello"))</script><br>
* The indexOf String "Hi" is <script>document.write(testArray.indexOf("Hi"))</script><br>
* The indexOf Boolean 'true' is <script>document.write(testArray.indexOf( true ))</script><br>
* The indexOf Number '5' is <script>document.write(testArray.indexOf( 5 ))</script><br>
* The indexOf Number '9' is <script>document.write(testArray.indexOf( 9 ))</script>
</p>
<p>2.0 A firstIndex parameter of 1 (positive offset test)<br>
* The indexOf String "Hi" is <script>document.write(testArray.indexOf("Hi",1))</script><br>
* The indexOf Boolean 'true' is <script>document.write(testArray.indexOf(true,1))</script><br>
* The indexOf Number 5 is <script>document.write(testArray.indexOf(5,1))</script><br>
* The indexOf Number 9 is <script>document.write(testArray.indexOf(9,1))</script>
* The indexOf String "Hi" is <script>document.write(testArray.indexOf("Hi",1))</script><br>
* The indexOf Boolean 'true' is <script>document.write(testArray.indexOf(true,1))</script><br>
* The indexOf Number 5 is <script>document.write(testArray.indexOf(5,1))</script><br>
* The indexOf Number 9 is <script>document.write(testArray.indexOf(9,1))</script>
</p>
<p>3.0 A firstIndex parameter of -4 (negative offset test)<br>
* The indexOf String "Hi" is <script>document.write(testArray.indexOf("Hi",-4))</script><br>
* The indexOf Boolean 'true' is <script>document.write(testArray.indexOf(true,-4))</script><br>
* The indexOf Number 5 is <script>document.write(testArray.indexOf(5,-4))</script><br>
* The indexOf Number 9 is <script>document.write(testArray.indexOf(9,-4))</script>
* The indexOf String "Hi" is <script>document.write(testArray.indexOf("Hi",-4))</script><br>
* The indexOf Boolean 'true' is <script>document.write(testArray.indexOf(true,-4))</script><br>
* The indexOf Number 5 is <script>document.write(testArray.indexOf(5,-4))</script><br>
* The indexOf Number 9 is <script>document.write(testArray.indexOf(9,-4))</script>
</p>
<p>4.0 A big positive firstIndex of 1000, to test the firstIndex > length<br>
* The indexOf Number '9' is <script>document.write(testArray.indexOf(9,1000))</script>
* The indexOf Number '9' is <script>document.write(testArray.indexOf(9,1000))</script>
</p>
<p>5.0 A big positive firstIndex of 4294967301, to test when firstIndex > width of int (32-bits)<br>
* The indexOf Boolean 'true' is <script>document.write(testArray.indexOf(true, 4294967301))</script>
* The indexOf Boolean 'true' is <script>document.write(testArray.indexOf(true, 4294967301))</script>
</p>
<p>6.0 No arguments<br>
* No arguments passed: <script>document.write(testArray.indexOf())</script><br>
* No arguments passed: <script>document.write(testArray2.indexOf())</script>
* No arguments passed: <script>document.write(testArray.indexOf())</script><br>
* No arguments passed: <script>document.write(testArray2.indexOf())</script>
</p>
<p>7.0 Looking for null<br>
* The indexOf null is <script>document.write(testArray.indexOf(null))</script><br>
* The indexOf null is <script>document.write(testArray2.indexOf(null))</script>
* The indexOf null is <script>document.write(testArray.indexOf(null))</script><br>
* The indexOf null is <script>document.write(testArray2.indexOf(null))</script>
</p>
<p>8.0 Extra arguments<br>
* The indexOf String "Hello" is <script>document.write(testArray.indexOf("Hello", 0, true))</script>
* The indexOf String "Hello" is <script>document.write(testArray.indexOf("Hello", 0, true))</script>
</p>
<p>9.0 NaN firstIndex<br>
* The indexOf String "Hi" is <script>document.write(testArray.indexOf("Hello", "Hey"))</script>
* The indexOf String "Hi" is <script>document.write(testArray.indexOf("Hello", "Hey"))</script>
</p>
<p>10.0 Small firstIndex<br>
* The indexOf Boolean 'true' is <script>document.write(testArray.indexOf(true, 0.45))</script>
* The indexOf Boolean 'true' is <script>document.write(testArray.indexOf(true, 0.45))</script>
</p>
<p>11.0 Negative firstIndex bigger than the length of the array<br>
* The indexOf Boolean 'true' is <script>document.write(testArray.indexOf(true, -1000))</script>
* The indexOf Boolean 'true' is <script>document.write(testArray.indexOf(true, -1000))</script>
</p>
<p>12.0 Negative firstIndex bigger than 32-bits<br>
* The indexOf Boolean 'true' is <script>document.write(testArray.indexOf(true, -5294967301))</script>
* The indexOf Boolean 'true' is <script>document.write(testArray.indexOf(true, -5294967301))</script>
</p>
<p>13.0 Looking for undefined<br>
* The indexOf undefined is <script>document.write(testArray.indexOf(undefined))</script><br>
* The indexOf undefined is <script>document.write(testArray2.indexOf(undefined))</script>
* The indexOf undefined is <script>document.write(testArray.indexOf(undefined))</script><br>
* The indexOf undefined is <script>document.write(testArray2.indexOf(undefined))</script><br>
* The indexOf undefined is <script>document.write(testArray4.indexOf(undefined))</script><br>
* The indexOf undefined is <script>document.write(testArray5.indexOf(undefined))</script><br>
* The indexOf undefined is <script>document.write(testArray6.indexOf(undefined))</script>
</p>
<p>14.0 Object using the Array prototype<br>
* The indexOf String "Hello" is <script>document.write(testArray3.indexOf("Hello"))</script><br>
* The indexOf String "Hi" is <script>document.write(testArray3.indexOf("Hi"))</script><br>
* The indexOf Boolean 'true' is <script>document.write(testArray3.indexOf(true))</script><br>
* The indexOf Number '5' is <script>document.write(testArray3.indexOf(5))</script><br>
* The indexOf Number '9' is <script>document.write(testArray3.indexOf(9))</script>
* The indexOf String "Hello" is <script>document.write(testArray3.indexOf("Hello"))</script><br>
* The indexOf String "Hi" is <script>document.write(testArray3.indexOf("Hi"))</script><br>
* The indexOf Boolean 'true' is <script>document.write(testArray3.indexOf(true))</script><br>
* The indexOf Number '5' is <script>document.write(testArray3.indexOf(5))</script><br>
* The indexOf Number '9' is <script>document.write(testArray3.indexOf(9))</script>
</p>
</body>
......
......@@ -11,6 +11,12 @@ PASS lastIndex is 3
PASS lastIndex is 0
PASS lastIndex is 0
PASS lastIndex is 3
PASS lastIndex is -1
PASS lastIndex is -1
PASS lastIndex is -1
PASS lastIndex is 19
PASS lastIndex is -1
PASS lastIndex is -1
PASS successfullyParsed is true
TEST COMPLETE
......
1.0 Behavior with Holes in Array
The following tests ensure that map skips holes in the array it constructs. You should see false and true printed in that order, followed by the printing of the indexes and values in two arrays, the first of which has no indexes and the second of which has one, whose value is NaN:
false
true
The following indexes are in the result array:
End indexes in the result array.
The following indexes are in the result array:
15: NaN
End indexes in the result array.
<html>
<head>
<script type="text/javascript">
function print(str) {
document.writeln(str+"<br/>");
}
if (window.layoutTestController)
layoutTestController.dumpAsText();
</script>
</head>
<body>
1.0 Behavior with Holes in Array<br/>
The following tests ensure that map skips holes in the array it constructs. You should see false and true printed in that order, followed by the printing of the indexes and values in two arrays, the first of which has no indexes and the second of which has one, whose value is NaN:<br/><br/>
<script>
function twice(element, index, array) {
return 2 * element;
}
var arr = [1, 2, 3, 4];
delete arr[2];
var res = arr.map(twice);
print(2 in res);
print(res[0] == 2 && res[1] == 4 && res[3] == 8);
arr = new Array(20);
res = arr.map(twice);
print("The following indexes are in the result array:");
for (var i in res)
print(i + ": " + res[i]);
print("End indexes in the result array.");
arr[15] = undefined;
res = arr.map(twice);
print("The following indexes are in the result array:");
for (var i in res)
print(i + ": " + res[i]);
print("End indexes in the result array.");
</script>
</body>
</html>
......@@ -58,3 +58,18 @@ Done with first array.
Testing element 12...
Done with second array.
7.0 Behavior with Holes in Arrays
This test checks that the callback function is not invoked for holes in the array. Five arrays are tested:
Testing element 2...
Testing element 8...
Testing element 1...
Testing element 4...
Done with first array.
Testing element undefined...
Done with second array.
Done with third array.
Done with fourth array.
Testing element undefined...
Done with fifth array.
......@@ -156,6 +156,38 @@ function isBigEnough(element, index, array) {
print("Done with first array.");
[12, 5, 8, 1, 44].some(isBigEnough);
print("Done with second array.");
</script>
<br/>
7.0 Behavior with Holes in Arrays<br/>
This test checks that the callback function is not invoked for holes in the array. Five arrays are tested:<br/><br/>
<script>
function isBigEnough(element, index, array) {
print("Testing element " + element + "...");
return (element >= 10);
}
var arr = [2, 5, 8, 1, 4];
delete arr[1];
arr.some(isBigEnough);
print("Done with first array.");
arr = [undefined];
arr.some(isBigEnough);
print("Done with second array.");
delete arr[0];
arr.some(isBigEnough);
print("Done with third array.");
arr = new Array(20);
arr.some(isBigEnough);
print("Done with fourth array.");
arr[17] = undefined;
arr.some(isBigEnough);
print("Done with fifth array.");
</script>
</body>
</html>
\ No newline at end of file
</html>
......@@ -80,5 +80,16 @@ shouldBe("accumulator.toString()", "[12, 5].toString()");
accumulator.length = 0;
shouldBeTrue("[12, 54, 18, 130, 44].every(isBigEnoughShortCircuit)");
shouldBe("accumulator.toString()", "[12, 54, 18, 130, 44].toString()");
debug("");
debug('7.0 Behavior for Holes in Arrays');
var arr = [5, 5, 5, 5];
delete arr[1];
function isNotUndefined(element, index, array) {
return typeof element !== "undefined";
}
shouldBeTrue("arr.every(isNotUndefined)");
arr = new Array(20);
shouldBeTrue("arr.every(isNotUndefined)");
successfullyParsed = true;
......@@ -23,4 +23,32 @@ shouldBe('lastIndex', '0');
lastIndex = testArray.lastIndexOf(2, -1);
shouldBe('lastIndex', '3');
delete testArray[1];
lastIndex = testArray.lastIndexOf(undefined);
shouldBe('lastIndex', '-1');
delete testArray[3];
lastIndex = testArray.lastIndexOf(undefined);
shouldBe('lastIndex', '-1');
testArray = new Array(20);
lastIndex = testArray.lastIndexOf(undefined);
shouldBe('lastIndex', '-1');
testArray[19] = undefined;
lastIndex = testArray.lastIndexOf(undefined);
shouldBe('lastIndex', '19');
lastIndex = testArray.lastIndexOf(undefined, 18);
shouldBe('lastIndex', '-1');
delete testArray[19];
lastIndex = testArray.lastIndexOf(undefined);
shouldBe('lastIndex', '-1');
var successfullyParsed = true;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment