DFG ToString generic cases should work correctly
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Mar 2013 05:23:55 +0000 (05:23 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Mar 2013 05:23:55 +0000 (05:23 +0000)
https://bugs.webkit.org/show_bug.cgi?id=112654
<rdar://problem/13447250>

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileToStringOnCell):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):

LayoutTests:

* fast/js/dfg-to-string-on-cell-expected.txt: Added.
* fast/js/dfg-to-string-on-cell.html: Added.
* fast/js/dfg-to-string-on-value-expected.txt: Added.
* fast/js/dfg-to-string-on-value.html: Added.
* fast/js/jsc-test-list:
* fast/js/script-tests/dfg-to-string-on-cell.js: Added.
(foo):
* fast/js/script-tests/dfg-to-string-on-value.js: Added.
(foo):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@146179 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/js/dfg-to-string-on-cell-expected.txt [new file with mode: 0644]
LayoutTests/fast/js/dfg-to-string-on-cell.html [new file with mode: 0644]
LayoutTests/fast/js/dfg-to-string-on-value-expected.txt [new file with mode: 0644]
LayoutTests/fast/js/dfg-to-string-on-value.html [new file with mode: 0644]
LayoutTests/fast/js/jsc-test-list
LayoutTests/fast/js/script-tests/dfg-to-string-on-cell.js [new file with mode: 0644]
LayoutTests/fast/js/script-tests/dfg-to-string-on-value.js [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

index c82e76b..351c818 100644 (file)
@@ -1,3 +1,21 @@
+2013-03-18  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG ToString generic cases should work correctly
+        https://bugs.webkit.org/show_bug.cgi?id=112654
+        <rdar://problem/13447250>
+
+        Reviewed by Geoffrey Garen.
+
+        * fast/js/dfg-to-string-on-cell-expected.txt: Added.
+        * fast/js/dfg-to-string-on-cell.html: Added.
+        * fast/js/dfg-to-string-on-value-expected.txt: Added.
+        * fast/js/dfg-to-string-on-value.html: Added.
+        * fast/js/jsc-test-list:
+        * fast/js/script-tests/dfg-to-string-on-cell.js: Added.
+        (foo):
+        * fast/js/script-tests/dfg-to-string-on-value.js: Added.
+        (foo):
+
 2013-03-18  Simon Fraser  <simon.fraser@apple.com>
 
         fast/dom/icon-url-property.html fails on Mac after r146173
diff --git a/LayoutTests/fast/js/dfg-to-string-on-cell-expected.txt b/LayoutTests/fast/js/dfg-to-string-on-cell-expected.txt
new file mode 100644 (file)
index 0000000..de8957c
--- /dev/null
@@ -0,0 +1,109 @@
+Tests that ToString on a cell works.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,1,2,3"
+PASS "" + foo("foo", i % 2 ? "hello" : [1, 2, 3]) is "foo,hello"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/js/dfg-to-string-on-cell.html b/LayoutTests/fast/js/dfg-to-string-on-cell.html
new file mode 100644 (file)
index 0000000..4a5dc77
--- /dev/null
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="resources/js-test-pre.js"></script>
+</head>
+<body>
+<script src="script-tests/dfg-to-string-on-cell.js"></script>
+<script src="resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/js/dfg-to-string-on-value-expected.txt b/LayoutTests/fast/js/dfg-to-string-on-value-expected.txt
new file mode 100644 (file)
index 0000000..d85bc20
--- /dev/null
@@ -0,0 +1,109 @@
+Tests that ToString on a possible-non-cell value works.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,42"
+PASS "" + foo("foo", i % 2 ? "hello" : 42) is "foo,hello"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/js/dfg-to-string-on-value.html b/LayoutTests/fast/js/dfg-to-string-on-value.html
new file mode 100644 (file)
index 0000000..cbb9bea
--- /dev/null
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="resources/js-test-pre.js"></script>
+</head>
+<body>
+<script src="script-tests/dfg-to-string-on-value.js"></script>
+<script src="resources/js-test-post.js"></script>
+</body>
+</html>
index adce18c..e208b82 100644 (file)
@@ -198,6 +198,8 @@ fast/js/dfg-to-string-bad-toString
 fast/js/dfg-to-string-bad-valueOf
 fast/js/dfg-to-string-int-or-string
 fast/js/dfg-to-string-int
+fast/js/dfg-to-string-on-cell
+fast/js/dfg-to-string-on-value
 fast/js/dfg-to-string-side-effect
 fast/js/dfg-to-string-side-effect-clobbers-toString
 fast/js/dfg-to-string-toString-becomes-bad-with-dictionary-string-prototype
diff --git a/LayoutTests/fast/js/script-tests/dfg-to-string-on-cell.js b/LayoutTests/fast/js/script-tests/dfg-to-string-on-cell.js
new file mode 100644 (file)
index 0000000..e6fe02b
--- /dev/null
@@ -0,0 +1,9 @@
+description("Tests that ToString on a cell works.");
+
+function foo(a, o) {
+    return [a, String(o)];
+}
+
+for (var i = 0; i < 100; ++i)
+    shouldBe("\"\" + foo(\"foo\", i % 2 ? \"hello\" : [1, 2, 3])", i % 2 ? "\"foo,hello\"" : "\"foo,1,2,3\"");
+
diff --git a/LayoutTests/fast/js/script-tests/dfg-to-string-on-value.js b/LayoutTests/fast/js/script-tests/dfg-to-string-on-value.js
new file mode 100644 (file)
index 0000000..0008e03
--- /dev/null
@@ -0,0 +1,9 @@
+description("Tests that ToString on a possible-non-cell value works.");
+
+function foo(a, o) {
+    return [a, String(o)];
+}
+
+for (var i = 0; i < 100; ++i)
+    shouldBe("\"\" + foo(\"foo\", i % 2 ? \"hello\" : 42)", i % 2 ? "\"foo,hello\"" : "\"foo,42\"");
+
index a59fcf7..8d33fe8 100644 (file)
@@ -1,3 +1,18 @@
+2013-03-18  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG ToString generic cases should work correctly
+        https://bugs.webkit.org/show_bug.cgi?id=112654
+        <rdar://problem/13447250>
+
+        Reviewed by Geoffrey Garen.
+
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileToStringOnCell):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+
 2013-03-18  Michael Saboff  <msaboff@apple.com>
 
         Unreviewed build fix for 32 bit builds.
index 6bc6754..912d09b 100644 (file)
@@ -4029,10 +4029,13 @@ void SpeculativeJIT::compileToStringOnCell(Node* node)
         flushRegisters();
         JITCompiler::Jump done;
         if (node->child1()->prediction() & SpecString) {
-            done = m_jit.branchPtr(
-                JITCompiler::Equal,
+            JITCompiler::Jump needCall = m_jit.branchPtr(
+                JITCompiler::NotEqual,
                 JITCompiler::Address(op1GPR, JSCell::structureOffset()),
                 TrustedImmPtr(m_jit.globalData()->stringStructure.get()));
+            m_jit.move(op1GPR, resultGPR);
+            done = m_jit.jump();
+            needCall.link(&m_jit);
         }
         callOperation(operationToStringOnCell, resultGPR, op1GPR);
         if (done.isSet())
index e923e75..ad1a896 100644 (file)
@@ -3337,13 +3337,16 @@ void SpeculativeJIT::compile(Node* node)
             
             JITCompiler::Jump done;
             if (node->child1()->prediction() & SpecString) {
-                JITCompiler::Jump slowPath = m_jit.branch32(
+                JITCompiler::Jump slowPath1 = m_jit.branch32(
                     JITCompiler::NotEqual, op1TagGPR, TrustedImm32(JSValue::CellTag));
-                done = m_jit.branchPtr(
-                    JITCompiler::Equal,
+                JITCompiler::Jump slowPath2 = m_jit.branchPtr(
+                    JITCompiler::NotEqual,
                     JITCompiler::Address(op1PayloadGPR, JSCell::structureOffset()),
                     TrustedImmPtr(m_jit.globalData()->stringStructure.get()));
-                slowPath.link(&m_jit);
+                m_jit.move(op1PayloadGPR, resultGPR);
+                done = m_jit.jump();
+                slowPath1.link(&m_jit);
+                slowPath2.link(&m_jit);
             }
             callOperation(operationToString, resultGPR, op1TagGPR, op1PayloadGPR);
             if (done.isSet())
index 39a3472..f005294 100644 (file)
@@ -3251,13 +3251,16 @@ void SpeculativeJIT::compile(Node* node)
             
             JITCompiler::Jump done;
             if (node->child1()->prediction() & SpecString) {
-                JITCompiler::Jump slowPath = m_jit.branchTest64(
+                JITCompiler::Jump slowPath1 = m_jit.branchTest64(
                     JITCompiler::NonZero, op1GPR, GPRInfo::tagMaskRegister);
-                done = m_jit.branchPtr(
-                    JITCompiler::Equal,
+                JITCompiler::Jump slowPath2 = m_jit.branchPtr(
+                    JITCompiler::NotEqual,
                     JITCompiler::Address(op1GPR, JSCell::structureOffset()),
                     TrustedImmPtr(m_jit.globalData()->stringStructure.get()));
-                slowPath.link(&m_jit);
+                m_jit.move(op1GPR, resultGPR);
+                done = m_jit.jump();
+                slowPath1.link(&m_jit);
+                slowPath2.link(&m_jit);
             }
             callOperation(operationToString, resultGPR, op1GPR);
             if (done.isSet())