Modified: trunk/LayoutTests/ChangeLog (117522 => 117523)
--- trunk/LayoutTests/ChangeLog 2012-05-18 01:28:03 UTC (rev 117522)
+++ trunk/LayoutTests/ChangeLog 2012-05-18 01:34:01 UTC (rev 117523)
@@ -1,3 +1,16 @@
+2012-05-17 Filip Pizlo <[email protected]>
+
+ Setting array index -1 and looping over array causes bad behavior
+ https://bugs.webkit.org/show_bug.cgi?id=86733
+ <rdar://problem/11477670>
+
+ Reviewed by Oliver Hunt.
+
+ * fast/js/dfg-negative-array-index-expected.txt: Added.
+ * fast/js/dfg-negative-array-index.html: Added.
+ * fast/js/script-tests/dfg-negative-array-index.js: Added.
+ (foo):
+
2012-05-17 Peter Kasting <[email protected]>
[chromium] More rebaselines/expectation updates.
Added: trunk/LayoutTests/fast/js/dfg-negative-array-index-expected.txt (0 => 117523)
--- trunk/LayoutTests/fast/js/dfg-negative-array-index-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-negative-array-index-expected.txt 2012-05-18 01:34:01 UTC (rev 117523)
@@ -0,0 +1,109 @@
+Tests that storing into a negative array index works right.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS array[-1] is 42
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/js/dfg-negative-array-index.html (0 => 117523)
--- trunk/LayoutTests/fast/js/dfg-negative-array-index.html (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-negative-array-index.html 2012-05-18 01:34:01 UTC (rev 117523)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/fast/js/script-tests/dfg-negative-array-index.js (0 => 117523)
--- trunk/LayoutTests/fast/js/script-tests/dfg-negative-array-index.js (rev 0)
+++ trunk/LayoutTests/fast/js/script-tests/dfg-negative-array-index.js 2012-05-18 01:34:01 UTC (rev 117523)
@@ -0,0 +1,14 @@
+description(
+"Tests that storing into a negative array index works right."
+);
+
+function foo(a, i) {
+ a[i] = 42;
+}
+
+for (var i = 0; i < 100; ++i) {
+ var array = [];
+ foo(array, -1);
+ shouldBe("array[-1]", "42");
+}
+
Modified: trunk/Source/_javascript_Core/ChangeLog (117522 => 117523)
--- trunk/Source/_javascript_Core/ChangeLog 2012-05-18 01:28:03 UTC (rev 117522)
+++ trunk/Source/_javascript_Core/ChangeLog 2012-05-18 01:34:01 UTC (rev 117523)
@@ -1,3 +1,13 @@
+2012-05-17 Filip Pizlo <[email protected]>
+
+ Setting array index -1 and looping over array causes bad behavior
+ https://bugs.webkit.org/show_bug.cgi?id=86733
+ <rdar://problem/11477670>
+
+ Reviewed by Oliver Hunt.
+
+ * dfg/DFGOperations.cpp:
+
2012-05-17 Geoffrey Garen <[email protected]>
Not reviewed.
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (117522 => 117523)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2012-05-18 01:28:03 UTC (rev 117522)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2012-05-18 01:34:01 UTC (rev 117523)
@@ -454,9 +454,16 @@
JSGlobalData* globalData = &exec->globalData();
NativeCallFrameTracer tracer(globalData, exec);
- // We should only get here if index is outside the existing vector.
- ASSERT(!array->canSetIndex(index));
- JSArray::putByIndex(array, exec, index, JSValue::decode(encodedValue), true);
+ if (index >= 0) {
+ // We should only get here if index is outside the existing vector.
+ ASSERT(!array->canSetIndex(index));
+ JSArray::putByIndex(array, exec, index, JSValue::decode(encodedValue), true);
+ return;
+ }
+
+ PutPropertySlot slot(true);
+ array->methodTable()->put(
+ array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
}
void DFG_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState* exec, JSArray* array, int32_t index, EncodedJSValue encodedValue)
@@ -464,9 +471,16 @@
JSGlobalData* globalData = &exec->globalData();
NativeCallFrameTracer tracer(globalData, exec);
- // We should only get here if index is outside the existing vector.
- ASSERT(!array->canSetIndex(index));
- JSArray::putByIndex(array, exec, index, JSValue::decode(encodedValue), false);
+ if (index >= 0) {
+ // We should only get here if index is outside the existing vector.
+ ASSERT(!array->canSetIndex(index));
+ JSArray::putByIndex(array, exec, index, JSValue::decode(encodedValue), false);
+ return;
+ }
+
+ PutPropertySlot slot(false);
+ array->methodTable()->put(
+ array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
}
EncodedJSValue DFG_OPERATION operationArrayPush(ExecState* exec, EncodedJSValue encodedValue, JSArray* array)