Diff
Modified: trunk/LayoutTests/ChangeLog (154289 => 154290)
--- trunk/LayoutTests/ChangeLog 2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/LayoutTests/ChangeLog 2013-08-19 19:40:13 UTC (rev 154290)
@@ -1,3 +1,16 @@
+2013-08-16 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-08-19 Chris Fleizach <[email protected]>
<https://webkit.org/b/119916> AX: WebKit is not exposing AXLanguage correctly
Added: trunk/LayoutTests/fast/js/dfg-activation-register-overwritten-in-throw-expected.txt (0 => 154290)
--- trunk/LayoutTests/fast/js/dfg-activation-register-overwritten-in-throw-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-activation-register-overwritten-in-throw-expected.txt 2013-08-19 19:40:13 UTC (rev 154290)
@@ -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: trunk/LayoutTests/fast/js/dfg-activation-register-overwritten-in-throw.html (0 => 154290)
--- trunk/LayoutTests/fast/js/dfg-activation-register-overwritten-in-throw.html (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-activation-register-overwritten-in-throw.html 2013-08-19 19:40:13 UTC (rev 154290)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/fast/js/script-tests/dfg-activation-register-overwritten-in-throw.js (0 => 154290)
--- trunk/LayoutTests/fast/js/script-tests/dfg-activation-register-overwritten-in-throw.js (rev 0)
+++ trunk/LayoutTests/fast/js/script-tests/dfg-activation-register-overwritten-in-throw.js 2013-08-19 19:40:13 UTC (rev 154290)
@@ -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);
+}
+
+while (!dfgCompiled({f:g})) {
+ try {
+ g()
+ } catch(e) {
+
+ }
+}
Modified: trunk/Source/_javascript_Core/ChangeLog (154289 => 154290)
--- trunk/Source/_javascript_Core/ChangeLog 2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/ChangeLog 2013-08-19 19:40:13 UTC (rev 154290)
@@ -1,3 +1,35 @@
+2013-08-16 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-08-19 Víctor Manuel Jáquez Leal <[email protected]>
<https://webkit.org/b/120008> [GTK][ARM] _javascript_core compilation is broken
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreter.h (154289 => 154290)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreter.h 2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreter.h 2013-08-19 19:40:13 UTC (rev 154290)
@@ -78,8 +78,7 @@
// basic blocks) interrogate the basic block's notion of the state at the head.
// Stores to local variables are handled in endBasicBlock(). This returns true
// if execution should continue past this node. Notably, it will return true
- // for block terminals, so long as those terminals are not Return or variants
- // of Throw.
+ // for block terminals, so long as those terminals are not Return or Unreachable.
//
// This is guaranteed to be equivalent to doing:
//
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (154289 => 154290)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2013-08-19 19:40:13 UTC (rev 154290)
@@ -1492,7 +1492,11 @@
case InlineStart:
case CountExecution:
break;
-
+
+ case Unreachable:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+
case LastNodeType:
RELEASE_ASSERT_NOT_REACHED();
break;
Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (154289 => 154290)
--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2013-08-19 19:40:13 UTC (rev 154290)
@@ -2864,13 +2864,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: trunk/Source/_javascript_Core/dfg/DFGClobberize.h (154289 => 154290)
--- trunk/Source/_javascript_Core/dfg/DFGClobberize.h 2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/dfg/DFGClobberize.h 2013-08-19 19:40:13 UTC (rev 154290)
@@ -132,6 +132,7 @@
case Throw:
case ForceOSRExit:
case Return:
+ case Unreachable:
write(SideState);
return;
Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (154289 => 154290)
--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2013-08-19 19:40:13 UTC (rev 154290)
@@ -880,6 +880,7 @@
case CountExecution:
case ForceOSRExit:
case CheckWatchdogTimer:
+ case Unreachable:
break;
#else
default:
Modified: trunk/Source/_javascript_Core/dfg/DFGFlushLivenessAnalysisPhase.cpp (154289 => 154290)
--- trunk/Source/_javascript_Core/dfg/DFGFlushLivenessAnalysisPhase.cpp 2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/dfg/DFGFlushLivenessAnalysisPhase.cpp 2013-08-19 19:40:13 UTC (rev 154290)
@@ -49,7 +49,7 @@
ASSERT(m_graph.m_form == SSA);
// Liveness is a backwards analysis; the roots are the blocks that
- // end in a terminal (Return/Throw/ThrowReferenceError). For now, we
+ // end in a terminal (Return/Unreachable). For now, we
// use a fixpoint formulation since liveness is a rapid analysis with
// convergence guaranteed after O(connectivity).
Modified: trunk/Source/_javascript_Core/dfg/DFGInPlaceAbstractState.cpp (154289 => 154290)
--- trunk/Source/_javascript_Core/dfg/DFGInPlaceAbstractState.cpp 2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/dfg/DFGInPlaceAbstractState.cpp 2013-08-19 19:40:13 UTC (rev 154290)
@@ -440,11 +440,10 @@
}
case Return:
- case Throw:
- case ThrowReferenceError:
+ case Unreachable:
ASSERT(basicBlock->cfaBranchDirection == InvalidBranchDirection);
return false;
-
+
default:
RELEASE_ASSERT_NOT_REACHED();
return false;
Modified: trunk/Source/_javascript_Core/dfg/DFGNode.h (154289 => 154290)
--- trunk/Source/_javascript_Core/dfg/DFGNode.h 2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/dfg/DFGNode.h 2013-08-19 19:40:13 UTC (rev 154290)
@@ -747,8 +747,7 @@
case Branch:
case Switch:
case Return:
- case Throw:
- case ThrowReferenceError:
+ case Unreachable:
return true;
default:
return false;
Modified: trunk/Source/_javascript_Core/dfg/DFGNodeType.h (154289 => 154290)
--- trunk/Source/_javascript_Core/dfg/DFGNodeType.h 2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/dfg/DFGNodeType.h 2013-08-19 19:40:13 UTC (rev 154290)
@@ -243,13 +243,16 @@
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(Switch, NodeMustGenerate) \
macro(Return, NodeMustGenerate) \
- macro(Throw, NodeMustGenerate) \
- macro(ThrowReferenceError, NodeMustGenerate) \
+ macro(Unreachable, NodeMustGenerate) \
\
/* Count execution. */\
macro(CountExecution, NodeMustGenerate) \
Modified: trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (154289 => 154290)
--- trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2013-08-19 19:40:13 UTC (rev 154290)
@@ -542,6 +542,7 @@
case Phantom:
case PutGlobalVar:
case CheckWatchdogTimer:
+ case Unreachable:
break;
// These gets ignored because it doesn't do anything.
Modified: trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h (154289 => 154290)
--- trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h 2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h 2013-08-19 19:40:13 UTC (rev 154290)
@@ -231,6 +231,7 @@
case ForceOSRExit:
case CheckWatchdogTimer:
case StringFromCharCode:
+ case Unreachable:
return true;
case GetByVal:
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (154289 => 154290)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2013-08-19 19:40:13 UTC (rev 154290)
@@ -4778,6 +4778,10 @@
noResult(node);
break;
+ case Unreachable:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+
case LastNodeType:
case Phi:
case Upsilon:
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (154289 => 154290)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2013-08-19 19:40:13 UTC (rev 154290)
@@ -4641,6 +4641,10 @@
// This is a no-op.
noResult(node);
break;
+
+ case Unreachable:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
case LastNodeType:
case Phi: