Diff
Modified: trunk/LayoutTests/ChangeLog (102708 => 102709)
--- trunk/LayoutTests/ChangeLog 2011-12-13 22:24:38 UTC (rev 102708)
+++ trunk/LayoutTests/ChangeLog 2011-12-13 23:17:43 UTC (rev 102709)
@@ -1,3 +1,20 @@
+2011-12-13 Oliver Hunt <[email protected]>
+
+ Arguments object doesn't handle mutation of length property correctly
+ https://bugs.webkit.org/show_bug.cgi?id=74454
+
+ Reviewed by Gavin Barraclough.
+
+ Add tests of mutated arguments.length
+
+ * fast/js/arguments-expected.txt:
+ * fast/js/script-tests/arguments.js:
+ (argumentLengthIs5):
+ (duplicateArgumentAndReturnLast_call):
+ (duplicateArgumentAndReturnFirst_call):
+ (duplicateArgumentAndReturnLast_apply):
+ (duplicateArgumentAndReturnFirst_apply):
+
2011-12-13 Vsevolod Vlasov <[email protected]>
Web Inspector: Network item view does not correctly decode "+" in request parameters.
Modified: trunk/LayoutTests/fast/js/arguments-expected.txt (102708 => 102709)
--- trunk/LayoutTests/fast/js/arguments-expected.txt 2011-12-13 22:24:38 UTC (rev 102708)
+++ trunk/LayoutTests/fast/js/arguments-expected.txt 2011-12-13 23:17:43 UTC (rev 102709)
@@ -18,6 +18,13 @@
PASS access_3(1, 2, 3, 4, 5) is 3
PASS access_4(1, 2, 3, 4, 5) is 4
PASS access_5(1, 2, 3, 4, 5) is 5
+PASS argumentLengthIs5() is 5
+PASS argumentLengthIs5(1,2,3,4,5) is 5
+PASS argumentLengthIs5(1,2,3,4,5,6,7,8,9,10) is 5
+PASS duplicateArgumentAndReturnLast_call(1) is 1
+PASS duplicateArgumentAndReturnFirst_call(1) is 1
+PASS duplicateArgumentAndReturnLast_apply(1) is 1
+PASS duplicateArgumentAndReturnFirst_apply(1) is 1
PASS tear_off_equal_access_1(1, 2, 3) is 1
PASS tear_off_equal_access_2(1, 2, 3) is 2
PASS tear_off_equal_access_3(1, 2, 3) is 3
Modified: trunk/LayoutTests/fast/js/script-tests/arguments.js (102708 => 102709)
--- trunk/LayoutTests/fast/js/script-tests/arguments.js 2011-12-13 22:24:38 UTC (rev 102708)
+++ trunk/LayoutTests/fast/js/script-tests/arguments.js 2011-12-13 23:17:43 UTC (rev 102709)
@@ -27,6 +27,31 @@
return arguments[4];
}
+function argumentLengthIs5() {
+ arguments.length = 5;
+ return arguments.length;
+}
+
+function duplicateArgumentAndReturnLast_call(a) {
+ Array.prototype.push.call(arguments, a);
+ return arguments[1];
+}
+
+function duplicateArgumentAndReturnFirst_call(a) {
+ Array.prototype.push.call(arguments, a);
+ return arguments[0];
+}
+
+function duplicateArgumentAndReturnLast_apply(a) {
+ Array.prototype.push.apply(arguments, arguments);
+ return arguments[1];
+}
+
+function duplicateArgumentAndReturnFirst_apply(a) {
+ Array.prototype.push.apply(arguments, arguments);
+ return arguments[0];
+}
+
shouldBe("access_1(1, 2, 3)", "1");
shouldBe("access_2(1, 2, 3)", "2");
shouldBe("access_3(1, 2, 3)", "3");
@@ -45,6 +70,14 @@
shouldBe("access_4(1, 2, 3, 4, 5)", "4");
shouldBe("access_5(1, 2, 3, 4, 5)", "5");
+shouldBe("argumentLengthIs5()", "5");
+shouldBe("argumentLengthIs5(1,2,3,4,5)", "5");
+shouldBe("argumentLengthIs5(1,2,3,4,5,6,7,8,9,10)", "5");
+shouldBe("duplicateArgumentAndReturnLast_call(1)", "1");
+shouldBe("duplicateArgumentAndReturnFirst_call(1)", "1");
+shouldBe("duplicateArgumentAndReturnLast_apply(1)", "1");
+shouldBe("duplicateArgumentAndReturnFirst_apply(1)", "1");
+
function f(a, b, c)
{
return arguments;
Modified: trunk/Source/_javascript_Core/ChangeLog (102708 => 102709)
--- trunk/Source/_javascript_Core/ChangeLog 2011-12-13 22:24:38 UTC (rev 102708)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-12-13 23:17:43 UTC (rev 102709)
@@ -1,3 +1,18 @@
+2011-12-13 Oliver Hunt <[email protected]>
+
+ Arguments object doesn't handle mutation of length property correctly
+ https://bugs.webkit.org/show_bug.cgi?id=74454
+
+ Reviewed by Gavin Barraclough.
+
+ Correct handling of arguments objects with overridden length property
+
+ * interpreter/Interpreter.cpp:
+ (JSC::loadVarargs):
+ * runtime/Arguments.cpp:
+ (JSC::Arguments::copyToArguments):
+ (JSC::Arguments::fillArgList):
+
2011-12-13 Filip Pizlo <[email protected]>
DFG GetByVal CSE rule should match PutByValAlias
Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (102708 => 102709)
--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2011-12-13 22:24:38 UTC (rev 102708)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2011-12-13 23:17:43 UTC (rev 102709)
@@ -495,7 +495,7 @@
if (asObject(arguments)->classInfo() == &Arguments::s_info) {
Arguments* argsObject = asArguments(arguments);
unsigned argCount = argsObject->length(callFrame);
- CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + argCount + 1 + RegisterFile::CallFrameHeaderSize);
+ CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + CallFrame::offsetFor(argCount + 1));
if (argCount > Arguments::MaxArguments || !registerFile->grow(newCallFrame->registers())) {
callFrame->globalData().exception = createStackOverflowError(callFrame);
return 0;
@@ -509,7 +509,7 @@
if (isJSArray(&callFrame->globalData(), arguments)) {
JSArray* array = asArray(arguments);
unsigned argCount = array->length();
- CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + argCount + 1 + RegisterFile::CallFrameHeaderSize);
+ CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + CallFrame::offsetFor(argCount + 1));
if (argCount > Arguments::MaxArguments || !registerFile->grow(newCallFrame->registers())) {
callFrame->globalData().exception = createStackOverflowError(callFrame);
return 0;
@@ -522,7 +522,7 @@
JSObject* argObject = asObject(arguments);
unsigned argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
- CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + argCount + 1 + RegisterFile::CallFrameHeaderSize);
+ CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + CallFrame::offsetFor(argCount + 1));
if (argCount > Arguments::MaxArguments || !registerFile->grow(newCallFrame->registers())) {
callFrame->globalData().exception = createStackOverflowError(callFrame);
return 0;
Modified: trunk/Source/_javascript_Core/runtime/Arguments.cpp (102708 => 102709)
--- trunk/Source/_javascript_Core/runtime/Arguments.cpp 2011-12-13 22:24:38 UTC (rev 102708)
+++ trunk/Source/_javascript_Core/runtime/Arguments.cpp 2011-12-13 23:17:43 UTC (rev 102709)
@@ -54,6 +54,12 @@
void Arguments::copyToArguments(ExecState* exec, CallFrame* callFrame, uint32_t length)
{
+ if (UNLIKELY(d->overrodeLength)) {
+ length = min(get(exec, exec->propertyNames().length).toUInt32(exec), length);
+ for (unsigned i = 0; i < length; i++)
+ callFrame->setArgument(i, get(exec, i));
+ return;
+ }
ASSERT(length == this->length(exec));
for (size_t i = 0; i < length; ++i) {
if (!d->deletedArguments || !d->deletedArguments[i])
@@ -65,6 +71,12 @@
void Arguments::fillArgList(ExecState* exec, MarkedArgumentBuffer& args)
{
+ if (UNLIKELY(d->overrodeLength)) {
+ unsigned length = get(exec, exec->propertyNames().length).toUInt32(exec);
+ for (unsigned i = 0; i < length; i++)
+ args.append(get(exec, i));
+ return;
+ }
uint32_t length = this->length(exec);
for (size_t i = 0; i < length; ++i) {
if (!d->deletedArguments || !d->deletedArguments[i])