Going to google.com/trends causes a crash
authoroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 19 Jun 2013 00:36:01 +0000 (00:36 +0000)
committeroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 19 Jun 2013 00:36:01 +0000 (00:36 +0000)
https://bugs.webkit.org/show_bug.cgi?id=117602

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

When handling op_throw, etc we need to flush the variables and arguments
for the entire inline stack, not just the top frame.

* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::flushAllArgumentsAndCapturedVariablesInInlineStack):
(JSC::DFG::ByteCodeParser::parseBlock):

LayoutTests:

Make sure we correctly initialise the appropriate argument registers,
and make sure we perform the tearoff correctly.

* fast/js/inline-arguments-tear-off-expected.txt: Added.
* fast/js/inline-arguments-tear-off.html: Added.
* fast/js/script-tests/inline-arguments-tear-off.js: Added.
(g):
(f):
(doStuff):

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

LayoutTests/ChangeLog
LayoutTests/fast/js/inline-arguments-tear-off-expected.txt [new file with mode: 0644]
LayoutTests/fast/js/inline-arguments-tear-off.html [new file with mode: 0644]
LayoutTests/fast/js/script-tests/inline-arguments-tear-off.js [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

index bbaf434..8595078 100644 (file)
@@ -1,3 +1,20 @@
+2013-06-18  Oliver Hunt  <oliver@apple.com>
+
+        Going to google.com/trends causes a crash
+        https://bugs.webkit.org/show_bug.cgi?id=117602
+
+        Reviewed by Geoffrey Garen.
+
+        Make sure we correctly initialise the appropriate argument registers,
+        and make sure we perform the tearoff correctly.
+
+        * fast/js/inline-arguments-tear-off-expected.txt: Added.
+        * fast/js/inline-arguments-tear-off.html: Added.
+        * fast/js/script-tests/inline-arguments-tear-off.js: Added.
+        (g):
+        (f):
+        (doStuff):
+
 2013-06-18  Benjamin Poulain  <bpoulain@apple.com>
 
         Rebaseline after system update
diff --git a/LayoutTests/fast/js/inline-arguments-tear-off-expected.txt b/LayoutTests/fast/js/inline-arguments-tear-off-expected.txt
new file mode 100644 (file)
index 0000000..9ad3017
--- /dev/null
@@ -0,0 +1,11 @@
+Ensure that we correctly tearoff the arguments objects when throwing from inlined function
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS fiftiethArguments[0] is 50
+PASS fiftiethArguments.length is 1
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/js/inline-arguments-tear-off.html b/LayoutTests/fast/js/inline-arguments-tear-off.html
new file mode 100644 (file)
index 0000000..e52e2a2
--- /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/inline-arguments-tear-off.js"></script>
+<script src="resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/js/script-tests/inline-arguments-tear-off.js b/LayoutTests/fast/js/script-tests/inline-arguments-tear-off.js
new file mode 100644 (file)
index 0000000..7acf6e7
--- /dev/null
@@ -0,0 +1,15 @@
+description("Ensure that we correctly tearoff the arguments objects when throwing from inlined function");
+
+var fiftiethArguments = null;
+
+function g(a) { if (a === 50) fiftiethArguments = arguments; f(); }
+function f() { doStuff();  }
+function doStuff() { throw {}; }
+
+
+for (var i = 0; i < 100; i++) { try {  g(i) } catch (e) { } }
+
+shouldBe("fiftiethArguments[0]", "50");
+shouldBe("fiftiethArguments.length", "1");
+
+
index a3fd855..5dcc71d 100644 (file)
@@ -1,3 +1,17 @@
+2013-06-18  Oliver Hunt  <oliver@apple.com>
+
+        Going to google.com/trends causes a crash
+        https://bugs.webkit.org/show_bug.cgi?id=117602
+
+        Reviewed by Geoffrey Garen.
+
+        When handling op_throw, etc we need to flush the variables and arguments
+        for the entire inline stack, not just the top frame.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::flushAllArgumentsAndCapturedVariablesInInlineStack):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+
 2013-06-18  Roger Fong  <roger_fong@apple.com>
 
         Replace tools32 folder with tools and update WebKit Windows solution accordingly.
index 0d46c81..a5f190a 100644 (file)
@@ -154,6 +154,8 @@ public:
     bool parse();
     
 private:
+    struct InlineStackEntry;
+
     // Just parse from m_currentIndex to the end of the current CodeBlock.
     void parseCodeBlock();
 
@@ -446,23 +448,34 @@ private:
         if (argumentPosition)
             argumentPosition->addVariable(variable);
     }
-    
-    void flushArgumentsAndCapturedVariables()
+
+    void flush(InlineStackEntry* inlineStackEntry)
     {
         int numArguments;
-        if (inlineCallFrame())
-            numArguments = inlineCallFrame()->arguments.size();
+        if (InlineCallFrame* inlineCallFrame = inlineStackEntry->m_inlineCallFrame)
+            numArguments = inlineCallFrame->arguments.size();
         else
-            numArguments = m_inlineStackTop->m_codeBlock->numParameters();
+            numArguments = inlineStackEntry->m_codeBlock->numParameters();
         for (unsigned argument = numArguments; argument-- > 1;)
-            flush(argumentToOperand(argument));
-        for (int local = 0; local < m_inlineStackTop->m_codeBlock->m_numVars; ++local) {
-            if (!m_inlineStackTop->m_codeBlock->isCaptured(local))
+            flushDirect(inlineStackEntry->remapOperand(argumentToOperand(argument)));
+        for (int local = 0; local < inlineStackEntry->m_codeBlock->m_numVars; ++local) {
+            if (!inlineStackEntry->m_codeBlock->isCaptured(local))
                 continue;
-            flush(local);
+            flushDirect(inlineStackEntry->remapOperand(local));
         }
     }
 
+    void flushAllArgumentsAndCapturedVariablesInInlineStack()
+    {
+        for (InlineStackEntry* inlineStackEntry = m_inlineStackTop; inlineStackEntry; inlineStackEntry = inlineStackEntry->m_caller)
+            flush(inlineStackEntry);
+    }
+
+    void flushArgumentsAndCapturedVariables()
+    {
+        flush(m_inlineStackTop);
+    }
+
     // Get an operand, and perform a ToInt32/ToNumber conversion on it.
     Node* getToInt32(int operand)
     {
@@ -3011,12 +3024,12 @@ bool ByteCodeParser::parseBlock(unsigned limit)
             LAST_OPCODE(op_end);
 
         case op_throw:
-            flushArgumentsAndCapturedVariables();
+            flushAllArgumentsAndCapturedVariablesInInlineStack();
             addToGraph(Throw, get(currentInstruction[1].u.operand));
             LAST_OPCODE(op_throw);
             
         case op_throw_static_error:
-            flushArgumentsAndCapturedVariables();
+            flushAllArgumentsAndCapturedVariablesInInlineStack();
             addToGraph(ThrowReferenceError);
             LAST_OPCODE(op_throw_static_error);