Diff
Modified: branches/safari-537.73-branch/LayoutTests/ChangeLog (157953 => 157954)
--- branches/safari-537.73-branch/LayoutTests/ChangeLog 2013-10-24 20:55:15 UTC (rev 157953)
+++ branches/safari-537.73-branch/LayoutTests/ChangeLog 2013-10-24 21:23:04 UTC (rev 157954)
@@ -1,3 +1,16 @@
+2013-10-24 Oliver Hunt <[email protected]>
+
+ <https://webkit.org/b/119860> Crash during exception unwinding
+
+ Reviewed by Filip Pizlo.
+
+ Add a test
+
+ * fast/js/dfg-activation-register-overwritten-in-throw-expected.txt: Added.
+ * fast/js/dfg-activation-register-overwritten-in-throw.html: Added.
+ * fast/js/script-tests/dfg-activation-register-overwritten-in-throw.js: Added.
+ (g):
+
2013-10-21 Lucas Forschler <[email protected]>
Merge r154217
Added: branches/safari-537.73-branch/LayoutTests/fast/js/dfg-activation-register-overwritten-in-throw-expected.txt (0 => 157954)
--- branches/safari-537.73-branch/LayoutTests/fast/js/dfg-activation-register-overwritten-in-throw-expected.txt (rev 0)
+++ branches/safari-537.73-branch/LayoutTests/fast/js/dfg-activation-register-overwritten-in-throw-expected.txt 2013-10-24 21:23:04 UTC (rev 157954)
@@ -0,0 +1,9 @@
+This tests that the DFG does not attempt to overwrite the activation register with undefined.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: branches/safari-537.73-branch/LayoutTests/fast/js/dfg-activation-register-overwritten-in-throw.html (0 => 157954)
--- branches/safari-537.73-branch/LayoutTests/fast/js/dfg-activation-register-overwritten-in-throw.html (rev 0)
+++ branches/safari-537.73-branch/LayoutTests/fast/js/dfg-activation-register-overwritten-in-throw.html 2013-10-24 21:23:04 UTC (rev 157954)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>
Added: branches/safari-537.73-branch/LayoutTests/fast/js/script-tests/dfg-activation-register-overwritten-in-throw.js (0 => 157954)
--- branches/safari-537.73-branch/LayoutTests/fast/js/script-tests/dfg-activation-register-overwritten-in-throw.js (rev 0)
+++ branches/safari-537.73-branch/LayoutTests/fast/js/script-tests/dfg-activation-register-overwritten-in-throw.js 2013-10-24 21:23:04 UTC (rev 157954)
@@ -0,0 +1,15 @@
+description(
+"This tests that the DFG does not attempt to overwrite the activation register with undefined."
+);
+
+function g() {
+ (eval("-7") = 0);
+}
+
+for (var i = 0; i < 10000; i++) {
+ try {
+ g()
+ } catch(e) {
+
+ }
+}
Modified: branches/safari-537.73-branch/Source/_javascript_Core/ChangeLog (157953 => 157954)
--- branches/safari-537.73-branch/Source/_javascript_Core/ChangeLog 2013-10-24 20:55:15 UTC (rev 157953)
+++ branches/safari-537.73-branch/Source/_javascript_Core/ChangeLog 2013-10-24 21:23:04 UTC (rev 157954)
@@ -1,3 +1,35 @@
+2013-10-24 Oliver Hunt <[email protected]>
+
+ <https://webkit.org/b/119860> Crash during exception unwinding
+
+ Reviewed by Filip Pizlo.
+
+ Add an "Unreachable" NodeType, and then rearrange op_throw and op_throw_reference_error
+ to plant Throw or ThrowReferenceError followed by a flush and then the Unreachable node.
+
+ We need this so that Throw and ThrowReferenceError no longer need to be treated as
+ terminals and the subsequent flush keeps the activation (and other registers) live.
+
+ * dfg/DFGAbstractInterpreterInlines.h:
+ (JSC::DFG::::executeEffects):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGClobberize.h:
+ (JSC::DFG::clobberize):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::isTerminal):
+ * dfg/DFGNodeType.h:
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSafeToExecute.h:
+ (JSC::DFG::safeToExecute):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
2013-10-21 Lucas Forschler <[email protected]>
Merge r154217
Modified: branches/safari-537.73-branch/Source/_javascript_Core/dfg/DFGAbstractState.cpp (157953 => 157954)
--- branches/safari-537.73-branch/Source/_javascript_Core/dfg/DFGAbstractState.cpp 2013-10-24 20:55:15 UTC (rev 157953)
+++ branches/safari-537.73-branch/Source/_javascript_Core/dfg/DFGAbstractState.cpp 2013-10-24 21:23:04 UTC (rev 157954)
@@ -1529,7 +1529,7 @@
// Again, sadly, we don't propagate the fact that we've done InstanceOf
forNode(node).set(SpecBoolean);
break;
-
+
case Phi:
case Flush:
case PhantomLocal:
@@ -1552,6 +1552,10 @@
forNode(node).makeTop();
break;
+ case Unreachable:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+
case ForceOSRExit:
node->setCanExit(true);
m_isValid = false;
@@ -1777,8 +1781,7 @@
}
case Return:
- case Throw:
- case ThrowReferenceError:
+ case Unreachable:
ASSERT(basicBlock->cfaBranchDirection == InvalidBranchDirection);
return false;
Modified: branches/safari-537.73-branch/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (157953 => 157954)
--- branches/safari-537.73-branch/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2013-10-24 20:55:15 UTC (rev 157953)
+++ branches/safari-537.73-branch/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2013-10-24 21:23:04 UTC (rev 157954)
@@ -3031,13 +3031,15 @@
LAST_OPCODE(op_end);
case op_throw:
+ addToGraph(Throw, get(currentInstruction[1].u.operand));
flushAllArgumentsAndCapturedVariablesInInlineStack();
- addToGraph(Throw, get(currentInstruction[1].u.operand));
+ addToGraph(Unreachable);
LAST_OPCODE(op_throw);
case op_throw_static_error:
+ addToGraph(ThrowReferenceError);
flushAllArgumentsAndCapturedVariablesInInlineStack();
- addToGraph(ThrowReferenceError);
+ addToGraph(Unreachable);
LAST_OPCODE(op_throw_static_error);
case op_call:
Modified: branches/safari-537.73-branch/Source/_javascript_Core/dfg/DFGConstantFoldingPhase.cpp (157953 => 157954)
--- branches/safari-537.73-branch/Source/_javascript_Core/dfg/DFGConstantFoldingPhase.cpp 2013-10-24 20:55:15 UTC (rev 157953)
+++ branches/safari-537.73-branch/Source/_javascript_Core/dfg/DFGConstantFoldingPhase.cpp 2013-10-24 21:23:04 UTC (rev 157954)
@@ -434,8 +434,7 @@
Node* node = block->at(indexInBlock);
switch (node->op()) {
case Return:
- case Throw:
- case ThrowReferenceError:
+ case Unreachable:
case ForceOSRExit:
// Do nothing. These nodes will already do the right thing.
break;
Modified: branches/safari-537.73-branch/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (157953 => 157954)
--- branches/safari-537.73-branch/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2013-10-24 20:55:15 UTC (rev 157953)
+++ branches/safari-537.73-branch/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2013-10-24 21:23:04 UTC (rev 157954)
@@ -873,6 +873,7 @@
case CountExecution:
case ForceOSRExit:
case CheckWatchdogTimer:
+ case Unreachable:
break;
#else
default:
Modified: branches/safari-537.73-branch/Source/_javascript_Core/dfg/DFGNode.h (157953 => 157954)
--- branches/safari-537.73-branch/Source/_javascript_Core/dfg/DFGNode.h 2013-10-24 20:55:15 UTC (rev 157953)
+++ branches/safari-537.73-branch/Source/_javascript_Core/dfg/DFGNode.h 2013-10-24 21:23:04 UTC (rev 157954)
@@ -676,8 +676,7 @@
case Jump:
case Branch:
case Return:
- case Throw:
- case ThrowReferenceError:
+ case Unreachable:
return true;
default:
return false;
Modified: branches/safari-537.73-branch/Source/_javascript_Core/dfg/DFGNodeType.h (157953 => 157954)
--- branches/safari-537.73-branch/Source/_javascript_Core/dfg/DFGNodeType.h 2013-10-24 20:55:15 UTC (rev 157953)
+++ branches/safari-537.73-branch/Source/_javascript_Core/dfg/DFGNodeType.h 2013-10-24 21:23:04 UTC (rev 157954)
@@ -250,12 +250,15 @@
macro(NewFunction, NodeResultJS) \
macro(NewFunctionExpression, NodeResultJS) \
\
+ /* These aren't terminals but always exit */ \
+ macro(Throw, NodeMustGenerate) \
+ macro(ThrowReferenceError, NodeMustGenerate) \
+ \
/* Block terminals. */\
macro(Jump, NodeMustGenerate) \
macro(Branch, NodeMustGenerate) \
macro(Return, NodeMustGenerate) \
- macro(Throw, NodeMustGenerate) \
- macro(ThrowReferenceError, NodeMustGenerate) \
+ macro(Unreachable, NodeMustGenerate) \
\
macro(GarbageValue, NodeResultJS | NodeClobbersWorld) \
\
Modified: branches/safari-537.73-branch/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (157953 => 157954)
--- branches/safari-537.73-branch/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2013-10-24 20:55:15 UTC (rev 157953)
+++ branches/safari-537.73-branch/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2013-10-24 21:23:04 UTC (rev 157954)
@@ -539,6 +539,7 @@
case PutGlobalVar:
case PutGlobalVarCheck:
case CheckWatchdogTimer:
+ case Unreachable:
break;
// These gets ignored because it doesn't do anything.
Modified: branches/safari-537.73-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (157953 => 157954)
--- branches/safari-537.73-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2013-10-24 20:55:15 UTC (rev 157953)
+++ branches/safari-537.73-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2013-10-24 21:23:04 UTC (rev 157954)
@@ -4955,6 +4955,10 @@
noResult(node);
break;
+ case Unreachable:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+
case Nop:
case LastNodeType:
RELEASE_ASSERT_NOT_REACHED();
Modified: branches/safari-537.73-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (157953 => 157954)
--- branches/safari-537.73-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2013-10-24 20:55:15 UTC (rev 157953)
+++ branches/safari-537.73-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2013-10-24 21:23:04 UTC (rev 157954)
@@ -4789,6 +4789,10 @@
// This is a no-op.
noResult(node);
break;
+
+ case Unreachable:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
case Nop:
RELEASE_ASSERT_NOT_REACHED();