Title: [128111] trunk
Revision
128111
Author
[email protected]
Date
2012-09-10 14:49:25 -0700 (Mon, 10 Sep 2012)

Log Message

DFG misses arguments tear-off for function.arguments if 'arguments' is used
https://bugs.webkit.org/show_bug.cgi?id=96227

Reviewed by Gavin Barraclough.

Source/_javascript_Core: 

We've decided not to allow function.arguments to alias the local
'arguments' object, or a local var or function named 'arguments'.
Aliasing complicates the implementation (cf, this bug) and can produce
surprising behavior for web programmers.

Eliminating the aliasing has the side-effect of fixing this bug.

The compatibilty story: function.arguments is deprecated, was never
specified, and throws an exception in strict mode, so we expect it to
disappear over time. Firefox does not alias to 'arguments'; Chrome
does, but not if you use eval or with; IE does; Safari did.

* dfg/DFGByteCodeParser.cpp: Noticed a little cleanup while verifying
this code. Use the CodeBlock method for better encapsulation.

* interpreter/Interpreter.cpp:
(JSC::Interpreter::retrieveArgumentsFromVMCode): Behavior change: don't
alias.

* tests/mozilla/js1_4/Functions/function-001.js:
(TestFunction_4): Updated test expectations for changed behavior.

LayoutTests: 

New test, and updated expectations.
 
* fast/js/script-tests/function-dot-arguments.js:
* fast/js/function-dot-arguments-expected.txt: Updated for new behavior.

* fast/js/dfg-tear-off-function-dot-arguments.html:
* fast/js/script-tests/dfg-tear-off-function-dot-arguments.js: Added. New test for bug cited here.

* fast/js/function-dot-arguments-identity-expected.txt:
* fast/js/function-dot-arguments-identity.html: Added. New test for new behavior.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (128110 => 128111)


--- trunk/LayoutTests/ChangeLog	2012-09-10 21:47:50 UTC (rev 128110)
+++ trunk/LayoutTests/ChangeLog	2012-09-10 21:49:25 UTC (rev 128111)
@@ -1,3 +1,21 @@
+2012-09-10  Geoffrey Garen  <[email protected]>
+
+        DFG misses arguments tear-off for function.arguments if 'arguments' is used
+        https://bugs.webkit.org/show_bug.cgi?id=96227
+
+        Reviewed by Gavin Barraclough.
+
+        New test, and updated expectations.
+ 
+        * fast/js/script-tests/function-dot-arguments.js:
+        * fast/js/function-dot-arguments-expected.txt: Updated for new behavior.
+
+        * fast/js/dfg-tear-off-function-dot-arguments.html:
+        * fast/js/script-tests/dfg-tear-off-function-dot-arguments.js: Added. New test for bug cited here.
+
+        * fast/js/function-dot-arguments-identity-expected.txt:
+        * fast/js/function-dot-arguments-identity.html: Added. New test for new behavior.
+
 2012-09-10  Fady Samuel  <[email protected]>
 
         Unreviewed Rebaseline for Chromium Win XP.

Added: trunk/LayoutTests/fast/js/dfg-tear-off-function-dot-arguments-expected.txt (0 => 128111)


--- trunk/LayoutTests/fast/js/dfg-tear-off-function-dot-arguments-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-tear-off-function-dot-arguments-expected.txt	2012-09-10 21:49:25 UTC (rev 128111)
@@ -0,0 +1,409 @@
+Tests a function that might create 'arguments' but doesn't, but does create function.arguments.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS thingy.length is 1
+PASS thingy[0] is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/js/dfg-tear-off-function-dot-arguments.html (0 => 128111)


--- trunk/LayoutTests/fast/js/dfg-tear-off-function-dot-arguments.html	                        (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-tear-off-function-dot-arguments.html	2012-09-10 21:49:25 UTC (rev 128111)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>

Modified: trunk/LayoutTests/fast/js/function-dot-arguments-expected.txt (128110 => 128111)


--- trunk/LayoutTests/fast/js/function-dot-arguments-expected.txt	2012-09-10 21:47:50 UTC (rev 128110)
+++ trunk/LayoutTests/fast/js/function-dot-arguments-expected.txt	2012-09-10 21:49:25 UTC (rev 128111)
@@ -8,18 +8,18 @@
 PASS basicTest('one', 'two', 'three')[1] is 'two'
 PASS lengthTest() is '0'
 PASS lengthTest('From', '%E5%8C%97%E4%BA%AC', 360, '/', 'webkit.org') is '5'
-PASS assignTest() is true
+PASS assignTest().toString() is '[object Arguments]'
 PASS assignVarUndefinedTest().toString() is '[object Arguments]'
 PASS assignVarUndefinedTest2().toString() is '[object Arguments]'
-PASS assignVarInitTest() is true
-PASS assignVarInitTest2() is true
+PASS assignVarInitTest().toString() is '[object Arguments]'
+PASS assignVarInitTest2().toString() is '[object Arguments]'
 PASS assignConstUndefinedTest().toString() is '[object Arguments]'
 PASS assignConstUndefinedTest2().toString() is '[object Arguments]'
-PASS assignConstInitTest() is true
-PASS assignConstInitTest2() is true
-PASS assignForInitTest() is true
-PASS assignForInitTest2() is true
-PASS assignForInInitTest() is true
+PASS assignConstInitTest().toString() is '[object Arguments]'
+PASS assignConstInitTest2().toString() is '[object Arguments]'
+PASS assignForInitTest().toString() is '[object Arguments]'
+PASS assignForInitTest2().toString() is '[object Arguments]'
+PASS assignForInInitTest().toString() is '[object Arguments]'
 PASS paramInitTest(true).toString() is '[object Arguments]'
 PASS paramFunctionConstructorInitTest(true).toString() is '[object Arguments]'
 PASS tearOffTest()[0] is true
@@ -27,9 +27,9 @@
 PASS lexicalArgumentsLiveRead1(0, 2, 3) is 1
 PASS lexicalArgumentsLiveRead2(1, 0, 3) is 2
 PASS lexicalArgumentsLiveRead3(1, 2, 0) is 3
-PASS lexicalArgumentsLiveWrite1(0, 2, 3) is 1
-PASS lexicalArgumentsLiveWrite2(1, 0, 3) is 2
-PASS lexicalArgumentsLiveWrite3(1, 2, 0) is 3
+PASS lexicalArgumentsLiveWrite1(0, 2, 3) is 0
+PASS lexicalArgumentsLiveWrite2(1, 0, 3) is 0
+PASS lexicalArgumentsLiveWrite3(1, 2, 0) is 0
 PASS argumentsNotLiveRead1(0, 2, 3) is 0
 PASS argumentsNotLiveRead2(1, 0, 3) is 0
 PASS argumentsNotLiveRead3(1, 2, 0) is 0
@@ -39,7 +39,7 @@
 PASS argumentsIdentity() is true
 PASS overwroteArgumentsInDynamicScope1() is true
 PASS overwroteArgumentsInDynamicScope2() is true
-PASS overwroteArgumentsInDynamicScope3() is true
+PASS overwroteArgumentsInDynamicScope3().toString() is '[object Arguments]'
 PASS successfullyParsed is true
 
 TEST COMPLETE

Added: trunk/LayoutTests/fast/js/function-dot-arguments-identity-expected.txt (0 => 128111)


--- trunk/LayoutTests/fast/js/function-dot-arguments-identity-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/js/function-dot-arguments-identity-expected.txt	2012-09-10 21:49:25 UTC (rev 128111)
@@ -0,0 +1,12 @@
+This tests verifies the identity of function.arguments vs 'arguments' used locally.
+
+PASS: getArguments() == arguments should be false and is.
+PASS: getArguments() == eval('arguments') should be false and is.
+PASS: getArguments() == arguments {eval present} should be false and is.
+PASS: getArguments() == arguments {function present} should be false and is.
+PASS: getArguments() == arguments {closure present} should be false and is.
+PASS: getArguments() == arguments {with present} should be false and is.
+PASS: getArguments() == arguments {catch present} should be false and is.
+PASS: getArguments() == arguments {var declaration} should be false and is.
+PASS: getArguments() == arguments {function declaration} should be false and is.
+

Added: trunk/LayoutTests/fast/js/function-dot-arguments-identity.html (0 => 128111)


--- trunk/LayoutTests/fast/js/function-dot-arguments-identity.html	                        (rev 0)
+++ trunk/LayoutTests/fast/js/function-dot-arguments-identity.html	2012-09-10 21:49:25 UTC (rev 128111)
@@ -0,0 +1,103 @@
+<p>This tests verifies the identity of function.arguments vs 'arguments' used locally.
+</p>
+<pre id="console"></pre>
+
+<script>
+function log(s)
+{
+	document.getElementById("console").appendChild(document.createTextNode(s + "\r\n"));
+}
+
+function shouldBe(a, aDescription, b)
+{
+	if (a == b) {
+		log("PASS: " + aDescription + " should be " + b + " and is.");
+		return;
+	}
+	log("FAIL: " + aDescription + " should be " + b + " but instead is " + a + ".");
+}
+
+if (window.testRunner) {
+	testRunner.dumpAsText();
+}
+
+function getArguments() { return arguments.callee.caller.arguments; }
+
+(function() {
+	shouldBe(
+		getArguments() == arguments,
+		"getArguments() == arguments",
+		false
+	);
+})();
+
+(function() {
+	shouldBe(
+		getArguments() == eval('arguments'),
+		"getArguments() == eval('arguments')",
+		false
+	);
+})();
+
+(function() {
+	eval("");
+	shouldBe(
+		getArguments() == arguments,
+		"getArguments() == arguments {eval present}",
+		false
+	);
+})();
+
+(function() {
+	var f = function() { };
+	shouldBe(
+		getArguments() == arguments,
+		"getArguments() == arguments {function present}",
+		false
+	);
+})();
+
+(function(x) {
+	var f = function() { return x; };
+	shouldBe(
+		getArguments() == arguments,
+		"getArguments() == arguments {closure present}",
+		false
+	);
+})(0);
+
+(function() {
+	with ({ }) { };
+	shouldBe(
+		getArguments() == arguments,
+		"getArguments() == arguments {with present}",
+		false
+	);
+})();
+
+(function() {
+	try { } catch(e) { };
+	shouldBe(
+		getArguments() == arguments,
+		"getArguments() == arguments {catch present}",
+		false
+	);
+})();
+(function() {
+	var arguments; 
+	shouldBe(
+		getArguments() == arguments,
+		"getArguments() == arguments {var declaration}",
+		false
+	);
+})();
+
+(function() {
+	function arguments() { };
+	shouldBe(
+		getArguments() == arguments,
+		"getArguments() == arguments {function declaration}",
+		false
+	);
+})();
+</script>

Added: trunk/LayoutTests/fast/js/script-tests/dfg-tear-off-function-dot-arguments.js (0 => 128111)


--- trunk/LayoutTests/fast/js/script-tests/dfg-tear-off-function-dot-arguments.js	                        (rev 0)
+++ trunk/LayoutTests/fast/js/script-tests/dfg-tear-off-function-dot-arguments.js	2012-09-10 21:49:25 UTC (rev 128111)
@@ -0,0 +1,22 @@
+description(
+"Tests a function that might create 'arguments' but doesn't, but does create function.arguments."
+);
+
+function bar() {
+    return foo.arguments;
+}
+
+function foo(p) {
+    var x = 42;
+    if (p)
+        return arguments[0];
+    else
+        return bar();
+}
+
+for (var i = 0; i < 200; ++i) {
+    var thingy = foo(false);
+    shouldBe("thingy.length", "1");
+    shouldBe("thingy[0]", "false");
+}
+

Modified: trunk/LayoutTests/fast/js/script-tests/function-dot-arguments.js (128110 => 128111)


--- trunk/LayoutTests/fast/js/script-tests/function-dot-arguments.js	2012-09-10 21:47:50 UTC (rev 128110)
+++ trunk/LayoutTests/fast/js/script-tests/function-dot-arguments.js	2012-09-10 21:49:25 UTC (rev 128111)
@@ -27,7 +27,7 @@
     arguments = true;
     return g();
 }
-shouldBeTrue("assignTest()");
+shouldBe("assignTest().toString()", "'[object Arguments]'");
 
 function assignVarUndefinedTest()
 {
@@ -63,7 +63,7 @@
     var arguments = true;
     return g();
 }
-shouldBeTrue("assignVarInitTest()");
+shouldBe("assignVarInitTest().toString()", "'[object Arguments]'");
 
 function assignVarInitTest2()
 {
@@ -75,7 +75,7 @@
     var a, arguments = true;
     return g();
 }
-shouldBeTrue("assignVarInitTest2()");
+shouldBe("assignVarInitTest2().toString()", "'[object Arguments]'");
 
 function assignConstUndefinedTest()
 {
@@ -111,7 +111,7 @@
     const arguments = true;
     return g();
 }
-shouldBeTrue("assignConstInitTest()");
+shouldBe("assignConstInitTest().toString()", "'[object Arguments]'");
 
 function assignConstInitTest2()
 {
@@ -123,7 +123,7 @@
     const a, arguments = true;
     return g();
 }
-shouldBeTrue("assignConstInitTest2()");
+shouldBe("assignConstInitTest2().toString()", "'[object Arguments]'");
 
 function assignForInitTest()
 {
@@ -135,7 +135,7 @@
     for (var arguments = true; false;) { }
     return g();
 }
-shouldBeTrue("assignForInitTest()");
+shouldBe("assignForInitTest().toString()", "'[object Arguments]'");
 
 function assignForInitTest2()
 {
@@ -147,7 +147,7 @@
     for (var a, arguments = true; false;) { }
     return g();
 }
-shouldBeTrue("assignForInitTest2()");
+shouldBe("assignForInitTest2().toString()", "'[object Arguments]'");
 
 function assignForInInitTest()
 {
@@ -159,7 +159,7 @@
     for (arguments = true; false;) { }
     return g();
 }
-shouldBeTrue("assignForInInitTest()");
+shouldBe("assignForInInitTest().toString()", "'[object Arguments]'");
 
 function paramInitTest(arguments)
 {
@@ -236,7 +236,7 @@
     lexicalArgumentsLiveWrite1.arguments[0] = 1;
     return a;
 }
-shouldBe("lexicalArgumentsLiveWrite1(0, 2, 3)", "1");
+shouldBe("lexicalArgumentsLiveWrite1(0, 2, 3)", "0");
 
 function lexicalArgumentsLiveWrite2(a, b, c)
 {
@@ -244,7 +244,7 @@
     lexicalArgumentsLiveWrite2.arguments[1] = 2;
     return b;
 }
-shouldBe("lexicalArgumentsLiveWrite2(1, 0, 3)", "2");
+shouldBe("lexicalArgumentsLiveWrite2(1, 0, 3)", "0");
 
 function lexicalArgumentsLiveWrite3(a, b, c)
 {
@@ -252,7 +252,7 @@
     lexicalArgumentsLiveWrite3.arguments[2] = 3;
     return c;
 }
-shouldBe("lexicalArgumentsLiveWrite3(1, 2, 0)", "3");
+shouldBe("lexicalArgumentsLiveWrite3(1, 2, 0)", "0");
 
 function argumentsNotLiveRead1(a, b, c)
 {
@@ -321,4 +321,4 @@
 }
 shouldBeTrue("overwroteArgumentsInDynamicScope1()");
 shouldBeTrue("overwroteArgumentsInDynamicScope2()");
-shouldBeTrue("overwroteArgumentsInDynamicScope3()");
+shouldBe("overwroteArgumentsInDynamicScope3().toString()", "'[object Arguments]'");

Modified: trunk/Source/_javascript_Core/ChangeLog (128110 => 128111)


--- trunk/Source/_javascript_Core/ChangeLog	2012-09-10 21:47:50 UTC (rev 128110)
+++ trunk/Source/_javascript_Core/ChangeLog	2012-09-10 21:49:25 UTC (rev 128111)
@@ -1,3 +1,32 @@
+2012-09-10  Geoffrey Garen  <[email protected]>
+
+        DFG misses arguments tear-off for function.arguments if 'arguments' is used
+        https://bugs.webkit.org/show_bug.cgi?id=96227
+
+        Reviewed by Gavin Barraclough.
+
+        We've decided not to allow function.arguments to alias the local
+        'arguments' object, or a local var or function named 'arguments'.
+        Aliasing complicates the implementation (cf, this bug) and can produce
+        surprising behavior for web programmers.
+
+        Eliminating the aliasing has the side-effect of fixing this bug.
+
+        The compatibilty story: function.arguments is deprecated, was never
+        specified, and throws an exception in strict mode, so we expect it to
+        disappear over time. Firefox does not alias to 'arguments'; Chrome
+        does, but not if you use eval or with; IE does; Safari did.
+
+        * dfg/DFGByteCodeParser.cpp: Noticed a little cleanup while verifying
+        this code. Use the CodeBlock method for better encapsulation.
+
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::retrieveArgumentsFromVMCode): Behavior change: don't
+        alias.
+
+        * tests/mozilla/js1_4/Functions/function-001.js:
+        (TestFunction_4): Updated test expectations for changed behavior.
+
 2012-09-10  Filip Pizlo  <[email protected]>
 
         offlineasm has some impossible to implement, and unused, instructions

Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (128110 => 128111)


--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2012-09-10 21:47:50 UTC (rev 128110)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2012-09-10 21:49:25 UTC (rev 128111)
@@ -3191,7 +3191,7 @@
                 inlineCallFrame.capturedVars.set(i);
         }
         
-        if (codeBlock->usesArguments() || codeBlock->needsActivation()) {
+        if (codeBlock->argumentsAreCaptured()) {
             for (int i = argumentCountIncludingThis; i--;)
                 inlineCallFrame.capturedVars.set(argumentToOperand(i) + inlineCallFrame.stackOffset);
         }

Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (128110 => 128111)


--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp	2012-09-10 21:47:50 UTC (rev 128110)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp	2012-09-10 21:49:25 UTC (rev 128111)
@@ -5105,19 +5105,6 @@
     if (!functionCallFrame)
         return jsNull();
 
-    CodeBlock* codeBlock = functionCallFrame->someCodeBlockForPossiblyInlinedCode();
-    if (codeBlock->usesArguments()) {
-        ASSERT(codeBlock->codeType() == FunctionCode);
-        int argumentsRegister = codeBlock->argumentsRegister();
-        int realArgumentsRegister = unmodifiedArgumentsRegister(argumentsRegister);
-        if (JSValue arguments = functionCallFrame->uncheckedR(argumentsRegister).jsValue())
-            return arguments;
-        JSValue arguments = JSValue(Arguments::create(callFrame->globalData(), functionCallFrame));
-        functionCallFrame->r(argumentsRegister) = arguments;
-        functionCallFrame->r(realArgumentsRegister) = arguments;
-        return arguments;
-    }
-
     Arguments* arguments = Arguments::create(functionCallFrame->globalData(), functionCallFrame);
     arguments->tearOff(functionCallFrame);
     return JSValue(arguments);

Modified: trunk/Source/_javascript_Core/tests/mozilla/js1_4/Functions/function-001.js (128110 => 128111)


--- trunk/Source/_javascript_Core/tests/mozilla/js1_4/Functions/function-001.js	2012-09-10 21:47:50 UTC (rev 128110)
+++ trunk/Source/_javascript_Core/tests/mozilla/js1_4/Functions/function-001.js	2012-09-10 21:49:25 UTC (rev 128111)
@@ -82,7 +82,7 @@
         SECTION,
         "return function.arguments when function contains an arguments property",
         "PASS",
-        TestFunction_4( "F", "A", "I", "L" ) +"");
+        TestFunction_4( "P", "A", "S", "S" ) +"");
 
     test();
 
@@ -100,7 +100,7 @@
     }
 
     function TestFunction_4( a, b, c, d, e ) {
-        var arguments = "PASS";
-        return TestFunction_4.arguments;
+        var arguments = "FAIL";
+        return Array.prototype.join.call(TestFunction_4.arguments, "");
     }
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to