<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[176357] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/176357">176357</a></dd>
<dt>Author</dt> <dd>joepeck@webkit.org</dd>
<dt>Date</dt> <dd>2014-11-19 15:49:36 -0800 (Wed, 19 Nov 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Web Inspector: Provide $exception in the console for the thrown exception value
https://bugs.webkit.org/show_bug.cgi?id=138726

Reviewed by Timothy Hatcher.

Source/JavaScriptCore:

* debugger/DebuggerScope.cpp:
(JSC::DebuggerScope::caughtValue):
* debugger/DebuggerScope.h:
Access the caught value if this scope is a catch scope.

* runtime/JSNameScope.h:
(JSC::JSNameScope::isFunctionNameScope):
(JSC::JSNameScope::isCatchScope):
(JSC::JSNameScope::value):
Provide an accessor for the single value in the JSNameScope (with / catch block).

* inspector/InjectedScriptSource.js:
Save the exception value and expose it via $exception. Since the command line api
is recreated on each evaluation, $exception is essentially readonly.

* inspector/ScriptDebugServer.h:
* inspector/ScriptDebugServer.cpp:
(Inspector::ScriptDebugServer::dispatchDidPause):
(Inspector::ScriptDebugServer::exceptionOrCaughtValue):
When pausing, get the exception or caught value. The exception will be provided
if we are breaking on an explicit exception. When inside of a catch block, we
can get the caught value by walking up the scope chain.

* inspector/agents/InspectorDebuggerAgent.h:
* inspector/agents/InspectorDebuggerAgent.cpp:
(Inspector::InspectorDebuggerAgent::InspectorDebuggerAgent):
(Inspector::InspectorDebuggerAgent::resume):
(Inspector::InspectorDebuggerAgent::stepOver):
(Inspector::InspectorDebuggerAgent::stepInto):
(Inspector::InspectorDebuggerAgent::stepOut):
Clearing state can be done in didContinue.

(Inspector::InspectorDebuggerAgent::didPause):
Set the exception value explicitly in the injected script when we have it.

(Inspector::InspectorDebuggerAgent::didContinue):
Clear state saved when we had paused, including clearly an exception value if needed.

(Inspector::InspectorDebuggerAgent::clearDebuggerBreakpointState):
(Inspector::InspectorDebuggerAgent::clearExceptionValue):
Call into the injected script only when needed.

* inspector/InjectedScript.cpp:
(Inspector::InjectedScript::setExceptionValue):
(Inspector::InjectedScript::clearExceptionValue):
* inspector/InjectedScript.h:
* inspector/InjectedScriptManager.cpp:
(Inspector::InjectedScriptManager::clearExceptionValue):
* inspector/InjectedScriptManager.h:
Clear on all injected scripts.

Source/WebCore:

Tests: inspector/debugger/command-line-api-exception-nested-catch.html
       inspector/debugger/command-line-api-exception.html

* inspector/CommandLineAPIModuleSource.js:
Expose $exception in the more complete command line API.

Source/WebInspectorUI:

* UserInterface/Base/Test.js:
(WebInspector.loaded):
In order to use RuntimeManager to execute in the global context or on the
active debugger call frame, we need to expose the quickConsole controller.

* UserInterface/Controllers/JavaScriptRuntimeCompletionProvider.js:
Expose $exception to completion when we paused because of an exception.

LayoutTests:

Provide some tests to ensure $exception is the value we expect at different times,
such as on the exception line, when there is no exception, or when stepping through
catch blocks (it should always be the most recent caught exception).

* inspector/debugger/command-line-api-exception-expected.txt: Added.
* inspector/debugger/command-line-api-exception-nested-catch-expected.txt: Added.
* inspector/debugger/command-line-api-exception-nested-catch.html: Added.
* inspector/debugger/command-line-api-exception.html: Added.
* inspector/debugger/resources/exceptions.js: Added.
(triggerUncaughtTypeException):
(triggerUncaughtReferenceException):
(triggerUncaughtSyntaxException):
(triggerUncaughtDOMException):
(throwString):
(throwNumber):
(throwNull):
(throwObject):
(throwNode):
(catcher):
(nestedCatchBlocks):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredebuggerDebuggerScopecpp">trunk/Source/JavaScriptCore/debugger/DebuggerScope.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredebuggerDebuggerScopeh">trunk/Source/JavaScriptCore/debugger/DebuggerScope.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorInjectedScriptcpp">trunk/Source/JavaScriptCore/inspector/InjectedScript.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorInjectedScripth">trunk/Source/JavaScriptCore/inspector/InjectedScript.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorInjectedScriptManagercpp">trunk/Source/JavaScriptCore/inspector/InjectedScriptManager.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorInjectedScriptManagerh">trunk/Source/JavaScriptCore/inspector/InjectedScriptManager.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorInjectedScriptSourcejs">trunk/Source/JavaScriptCore/inspector/InjectedScriptSource.js</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorScriptDebugServercpp">trunk/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorScriptDebugServerh">trunk/Source/JavaScriptCore/inspector/ScriptDebugServer.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectoragentsInspectorDebuggerAgentcpp">trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectoragentsInspectorDebuggerAgenth">trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSNameScopeh">trunk/Source/JavaScriptCore/runtime/JSNameScope.h</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreinspectorCommandLineAPIModuleSourcejs">trunk/Source/WebCore/inspector/CommandLineAPIModuleSource.js</a></li>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceBaseTestjs">trunk/Source/WebInspectorUI/UserInterface/Base/Test.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceControllersJavaScriptRuntimeCompletionProviderjs">trunk/Source/WebInspectorUI/UserInterface/Controllers/JavaScriptRuntimeCompletionProvider.js</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsinspectordebuggercommandlineapiexceptionexpectedtxt">trunk/LayoutTests/inspector/debugger/command-line-api-exception-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectordebuggercommandlineapiexceptionnestedcatchexpectedtxt">trunk/LayoutTests/inspector/debugger/command-line-api-exception-nested-catch-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectordebuggercommandlineapiexceptionnestedcatchhtml">trunk/LayoutTests/inspector/debugger/command-line-api-exception-nested-catch.html</a></li>
<li><a href="#trunkLayoutTestsinspectordebuggercommandlineapiexceptionhtml">trunk/LayoutTests/inspector/debugger/command-line-api-exception.html</a></li>
<li><a href="#trunkLayoutTestsinspectordebuggerresourcesexceptionsjs">trunk/LayoutTests/inspector/debugger/resources/exceptions.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (176356 => 176357)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-11-19 23:48:53 UTC (rev 176356)
+++ trunk/LayoutTests/ChangeLog        2014-11-19 23:49:36 UTC (rev 176357)
</span><span class="lines">@@ -1,3 +1,31 @@
</span><ins>+2014-11-19  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
+
+        Web Inspector: Provide $exception in the console for the thrown exception value
+        https://bugs.webkit.org/show_bug.cgi?id=138726
+
+        Reviewed by Timothy Hatcher.
+
+        Provide some tests to ensure $exception is the value we expect at different times,
+        such as on the exception line, when there is no exception, or when stepping through
+        catch blocks (it should always be the most recent caught exception).
+
+        * inspector/debugger/command-line-api-exception-expected.txt: Added.
+        * inspector/debugger/command-line-api-exception-nested-catch-expected.txt: Added.
+        * inspector/debugger/command-line-api-exception-nested-catch.html: Added.
+        * inspector/debugger/command-line-api-exception.html: Added.
+        * inspector/debugger/resources/exceptions.js: Added.
+        (triggerUncaughtTypeException):
+        (triggerUncaughtReferenceException):
+        (triggerUncaughtSyntaxException):
+        (triggerUncaughtDOMException):
+        (throwString):
+        (throwNumber):
+        (throwNull):
+        (throwObject):
+        (throwNode):
+        (catcher):
+        (nestedCatchBlocks):
+
</ins><span class="cx"> 2014-11-19  David Hyatt  &lt;hyatt@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Images/replaced elements that are as tall as a page should be on their own page
</span></span></pre></div>
<a id="trunkLayoutTestsinspectordebuggercommandlineapiexceptionexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/debugger/command-line-api-exception-expected.txt (0 => 176357)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/debugger/command-line-api-exception-expected.txt                                (rev 0)
+++ trunk/LayoutTests/inspector/debugger/command-line-api-exception-expected.txt        2014-11-19 23:49:36 UTC (rev 176357)
</span><span class="lines">@@ -0,0 +1,32 @@
</span><ins>+CONSOLE MESSAGE: line 4: TypeError: undefined is not an object (evaluating '[].x.x')
+CONSOLE MESSAGE: line 10: ReferenceError: Can't find variable: variableThatDoesNotExist
+CONSOLE MESSAGE: line 16: SyntaxError: Unexpected token ')'
+CONSOLE MESSAGE: line 22: IndexSizeError: DOM Exception 1: Index or size was negative, or greater than the allowed value.
+CONSOLE MESSAGE: line 27: thrown string
+CONSOLE MESSAGE: line 32: 123.456
+CONSOLE MESSAGE: line 37: null
+CONSOLE MESSAGE: line 42: [object Object]
+CONSOLE MESSAGE: line 47: [object HTMLBodyElement]
+CONSOLE MESSAGE: line 55: CATCHER: TypeError: undefined is not an object (evaluating '[].x.x')
+CONSOLE MESSAGE: line 55: CATCHER: thrown string
+CONSOLE MESSAGE: line 55: CATCHER: [object Object]
+Checks that $exception is available and accurate in evaluations when paused on an exception.
+
+BEFORE: $exception =&gt; undefined
+PAUSE #1: $exception =&gt; TypeError: undefined is not an object (evaluating '[].x.x')
+PAUSE #2: $exception =&gt; ReferenceError: Can't find variable: variableThatDoesNotExist
+PAUSE #3: $exception =&gt; SyntaxError: Unexpected token ')'
+PAUSE #4: $exception =&gt; DOMException
+PAUSE #5: $exception =&gt; thrown string
+PAUSE #6: $exception =&gt; 123.456
+PAUSE #7: $exception =&gt; null
+PAUSE #8: $exception =&gt; Object
+PAUSE #9: $exception =&gt; body
+PAUSE #10: $exception =&gt; TypeError: undefined is not an object (evaluating '[].x.x')
+STEPPED OUT TO CATCH BLOCK: $exception === e ? true
+PAUSE #11: $exception =&gt; thrown string
+STEPPED OUT TO CATCH BLOCK: $exception === e ? true
+PAUSE #12: $exception =&gt; Object
+STEPPED OUT TO CATCH BLOCK: $exception === e ? true
+AFTER: $exception =&gt; undefined
+
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectordebuggercommandlineapiexceptionnestedcatchexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/debugger/command-line-api-exception-nested-catch-expected.txt (0 => 176357)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/debugger/command-line-api-exception-nested-catch-expected.txt                                (rev 0)
+++ trunk/LayoutTests/inspector/debugger/command-line-api-exception-nested-catch-expected.txt        2014-11-19 23:49:36 UTC (rev 176357)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+CONSOLE MESSAGE: line 67: inner exception
+CONSOLE MESSAGE: line 69: outer exception
+Checks that $exception is the value of the current exception, even in nested catch blocks.
+
+BEFORE : $exception =&gt; undefined
+OUTER 1: $exception =&gt; outer exception
+INNER 1: $exception =&gt; inner exception
+INNER 2: $exception =&gt; inner exception
+  CATCH: $exception === e2 ? true
+OUTER 2: $exception =&gt; outer exception
+  CATCH: $exception === e1 ? true
+AFTER  : $exception =&gt; undefined
+
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectordebuggercommandlineapiexceptionnestedcatchhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/debugger/command-line-api-exception-nested-catch.html (0 => 176357)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/debugger/command-line-api-exception-nested-catch.html                                (rev 0)
+++ trunk/LayoutTests/inspector/debugger/command-line-api-exception-nested-catch.html        2014-11-19 23:49:36 UTC (rev 176357)
</span><span class="lines">@@ -0,0 +1,84 @@
</span><ins>+&lt;!doctype html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script type=&quot;text/javascript&quot; src=&quot;../../http/tests/inspector/inspector-test.js&quot;&gt;&lt;/script&gt;
+&lt;script type=&quot;text/javascript&quot; src=&quot;./resources/exceptions.js&quot;&gt;&lt;/script&gt;
+&lt;script&gt;
+function triggerException()
+{
+    // We expect uncaught exceptions, so avoid logs for them.
+    window.onerror = function(){};
+    setTimeout(nestedCatchBlocks, 0);
+}
+
+function test()
+{
+    WebInspector.debuggerManager.allExceptionsBreakpoint.disabled = false;
+
+    function dumpCommandLineAPIValue(prefix) {
+        WebInspector.runtimeManager.evaluateInInspectedWindow(&quot;$exception&quot;, &quot;test&quot;, true, true, false, function(result, wasThrown) {
+            InspectorTest.log(prefix + &quot;: $exception =&gt; &quot; + result.description);
+        });
+    }
+
+    function checkIfExceptionValueMatchesVariable(varName) {
+        WebInspector.runtimeManager.evaluateInInspectedWindow(&quot;$exception === &quot; + varName, &quot;test&quot;, true, true, false, function(result, wasThrown) {
+            InspectorTest.log(&quot;  CATCH: $exception === &quot; + varName + &quot; ? &quot; + result.description);
+        });
+    }
+
+    var done = false;
+    var phase = 0;
+
+    WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.CallFramesDidChange, function(event) {
+        if (done)
+            return;
+
+        phase++;
+
+        // Skip past the first pause to the second pause.
+        if (phase === 1) {
+            dumpCommandLineAPIValue(&quot;OUTER 1&quot;);
+            WebInspector.debuggerManager.resume();
+            return;
+        }
+
+        // Paused on the exception in the inner try, step over to get into the inner catch.
+        if (phase === 2) {
+            dumpCommandLineAPIValue(&quot;INNER 1&quot;);
+            WebInspector.debuggerManager.stepOver();
+            return;
+        }
+
+        // Paused in the inner catch, verify $exception is &quot;inner exception&quot;.
+        if (phase === 3) {
+            dumpCommandLineAPIValue(&quot;INNER 2&quot;);
+            checkIfExceptionValueMatchesVariable(&quot;e2&quot;);
+            WebInspector.debuggerManager.stepOver();
+            return;
+        }
+        
+        // Stepped into the outer catch, verify $exception is &quot;outer exception&quot;.
+        if (phase === 4) {
+            dumpCommandLineAPIValue(&quot;OUTER 2&quot;);
+            checkIfExceptionValueMatchesVariable(&quot;e1&quot;);
+            WebInspector.debuggerManager.resume();
+            return;
+        }
+    });
+
+    WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.Resumed, function(event) {
+        done = true;
+        dumpCommandLineAPIValue(&quot;AFTER  &quot;);
+        InspectorTest.completeTest();
+    });
+
+    dumpCommandLineAPIValue(&quot;BEFORE &quot;);
+    InspectorTest.evaluateInPage(&quot;triggerException()&quot;);
+}
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body onload=&quot;runTest()&quot;&gt;
+    &lt;p&gt;Checks that &lt;code&gt;$exception&lt;/code&gt; is the value of the current exception, even in nested catch blocks.&lt;/p&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectordebuggercommandlineapiexceptionhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/debugger/command-line-api-exception.html (0 => 176357)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/debugger/command-line-api-exception.html                                (rev 0)
+++ trunk/LayoutTests/inspector/debugger/command-line-api-exception.html        2014-11-19 23:49:36 UTC (rev 176357)
</span><span class="lines">@@ -0,0 +1,98 @@
</span><ins>+&lt;!doctype html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script type=&quot;text/javascript&quot; src=&quot;../../http/tests/inspector/inspector-test.js&quot;&gt;&lt;/script&gt;
+&lt;script type=&quot;text/javascript&quot; src=&quot;./resources/exceptions.js&quot;&gt;&lt;/script&gt;
+&lt;script&gt;
+var exceptionIndex = 0;
+var exceptionCausers = [
+    triggerUncaughtTypeException,
+    triggerUncaughtReferenceException,
+    triggerUncaughtSyntaxException,
+    triggerUncaughtDOMException,
+    throwString,
+    throwNumber,
+    throwNull,
+    throwObject,
+    throwNode,
+    function() { catcher(triggerUncaughtTypeException); },
+    function() { catcher(throwString); },
+    function() { catcher(throwObject); },
+];
+
+
+function triggerNextException()
+{
+    // We expect uncaught exceptions, so avoid logs for them.
+    window.onerror = function(){};
+
+    setTimeout(function() {
+        exceptionCausers[exceptionIndex++]();
+    }, 0);
+}
+
+function test()
+{
+    WebInspector.debuggerManager.allExceptionsBreakpoint.disabled = false;
+
+    function triggerNextException() {
+        InspectorTest.evaluateInPage(&quot;triggerNextException()&quot;);
+    }
+
+    function dumpCommandLineAPIValue(prefix) {
+        WebInspector.runtimeManager.evaluateInInspectedWindow(&quot;$exception&quot;, &quot;test&quot;, true, true, false, function(result, wasThrown) {
+            InspectorTest.log(prefix + &quot;: $exception =&gt; &quot; + result.description);
+        });
+    }
+
+    function checkIfExceptionValueMatchesCatchVariable() {
+        WebInspector.runtimeManager.evaluateInInspectedWindow(&quot;$exception === e&quot;, &quot;test&quot;, true, true, false, function(result, wasThrown) {
+            InspectorTest.log(&quot;STEPPED OUT TO CATCH BLOCK: $exception === e ? &quot; + result.description);
+        });
+    }
+
+    var pauses = 0;
+    var stepping = false;
+    var done = false;
+    const pointWhereExpectionsAreBeingCaught = 9;
+    const expectedPauses = 12;
+
+    WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.CallFramesDidChange, function(event) {
+        if (done)
+            return;
+
+        if (!stepping) {
+            dumpCommandLineAPIValue(&quot;PAUSE #&quot; + (++pauses));
+            if (pauses &gt; pointWhereExpectionsAreBeingCaught) {
+                WebInspector.debuggerManager.stepOut();
+                stepping = true;
+                return;
+            }
+        } else {
+            checkIfExceptionValueMatchesCatchVariable();
+            stepping = false;
+        }
+
+        WebInspector.debuggerManager.resume();
+
+        if (pauses !== expectedPauses) {
+            triggerNextException();
+            return;
+        }
+    });
+
+    WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.Resumed, function(event) {
+        done = true;
+        dumpCommandLineAPIValue(&quot;AFTER&quot;);
+        InspectorTest.completeTest();
+    });
+
+    dumpCommandLineAPIValue(&quot;BEFORE&quot;);
+    triggerNextException();
+}
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body onload=&quot;runTest()&quot;&gt;
+    &lt;p&gt;Checks that &lt;code&gt;$exception&lt;/code&gt; is available and accurate in evaluations when paused on an exception.&lt;/p&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectordebuggerresourcesexceptionsjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/debugger/resources/exceptions.js (0 => 176357)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/debugger/resources/exceptions.js                                (rev 0)
+++ trunk/LayoutTests/inspector/debugger/resources/exceptions.js        2014-11-19 23:49:36 UTC (rev 176357)
</span><span class="lines">@@ -0,0 +1,71 @@
</span><ins>+function triggerUncaughtTypeException()
+{
+    // Exception: TypeError: undefined is not an object (evaluating '[].x.x')
+    [].x.x;
+}
+
+function triggerUncaughtReferenceException()
+{
+    // Exception: ReferenceError: Can't find variable: variableThatDoesNotExist
+    variableThatDoesNotExist += 1;
+}
+
+function triggerUncaughtSyntaxException()
+{
+    // Exception: SyntaxError: Unexpected token ')'
+    eval(&quot;if()&quot;);
+}
+
+function triggerUncaughtDOMException()
+{
+    // Error: IndexSizeError: DOM Exception 1
+    document.createTextNode(&quot;&quot;).splitText(100);
+}
+
+function throwString()
+{
+    throw &quot;thrown string&quot;;
+}
+
+function throwNumber()
+{
+    throw 123.456;
+}
+
+function throwNull()
+{
+    throw null;
+}
+
+function throwObject()
+{
+    throw {x:1,y:2};
+}
+
+function throwNode()
+{
+    throw document.body;
+}
+
+function catcher(func)
+{
+    try {
+        func();
+    } catch (e) {
+        console.log(&quot;CATCHER: &quot; + e);
+    }
+}
+
+function nestedCatchBlocks()
+{
+    try {
+        throw &quot;outer exception&quot;;
+    } catch (e1) {
+        try {
+            throw &quot;inner exception&quot;;
+        } catch (e2) {
+            console.log(e2);
+        }
+        console.log(e1);
+    }
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (176356 => 176357)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-11-19 23:48:53 UTC (rev 176356)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-11-19 23:49:36 UTC (rev 176357)
</span><span class="lines">@@ -1,5 +1,63 @@
</span><span class="cx"> 2014-11-19  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Web Inspector: Provide $exception in the console for the thrown exception value
+        https://bugs.webkit.org/show_bug.cgi?id=138726
+
+        Reviewed by Timothy Hatcher.
+
+        * debugger/DebuggerScope.cpp:
+        (JSC::DebuggerScope::caughtValue):
+        * debugger/DebuggerScope.h:
+        Access the caught value if this scope is a catch scope.
+
+        * runtime/JSNameScope.h:
+        (JSC::JSNameScope::isFunctionNameScope):
+        (JSC::JSNameScope::isCatchScope):
+        (JSC::JSNameScope::value):
+        Provide an accessor for the single value in the JSNameScope (with / catch block).
+
+        * inspector/InjectedScriptSource.js:
+        Save the exception value and expose it via $exception. Since the command line api
+        is recreated on each evaluation, $exception is essentially readonly.
+
+        * inspector/ScriptDebugServer.h:
+        * inspector/ScriptDebugServer.cpp:
+        (Inspector::ScriptDebugServer::dispatchDidPause):
+        (Inspector::ScriptDebugServer::exceptionOrCaughtValue):
+        When pausing, get the exception or caught value. The exception will be provided
+        if we are breaking on an explicit exception. When inside of a catch block, we
+        can get the caught value by walking up the scope chain.
+
+        * inspector/agents/InspectorDebuggerAgent.h:
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::InspectorDebuggerAgent::InspectorDebuggerAgent):
+        (Inspector::InspectorDebuggerAgent::resume):
+        (Inspector::InspectorDebuggerAgent::stepOver):
+        (Inspector::InspectorDebuggerAgent::stepInto):
+        (Inspector::InspectorDebuggerAgent::stepOut):
+        Clearing state can be done in didContinue.
+
+        (Inspector::InspectorDebuggerAgent::didPause):
+        Set the exception value explicitly in the injected script when we have it.
+
+        (Inspector::InspectorDebuggerAgent::didContinue):
+        Clear state saved when we had paused, including clearly an exception value if needed.
+
+        (Inspector::InspectorDebuggerAgent::clearDebuggerBreakpointState):
+        (Inspector::InspectorDebuggerAgent::clearExceptionValue):
+        Call into the injected script only when needed.
+
+        * inspector/InjectedScript.cpp:
+        (Inspector::InjectedScript::setExceptionValue):
+        (Inspector::InjectedScript::clearExceptionValue):
+        * inspector/InjectedScript.h:
+        * inspector/InjectedScriptManager.cpp:
+        (Inspector::InjectedScriptManager::clearExceptionValue):
+        * inspector/InjectedScriptManager.h:
+        Clear on all injected scripts.
+
+2014-11-19  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
+
</ins><span class="cx">         Unreviewed build fixes after r176329.
</span><span class="cx"> 
</span><span class="cx">           - export all of the codegen python files as they are included by the main generator
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredebuggerDebuggerScopecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/debugger/DebuggerScope.cpp (176356 => 176357)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/debugger/DebuggerScope.cpp        2014-11-19 23:48:53 UTC (rev 176356)
+++ trunk/Source/JavaScriptCore/debugger/DebuggerScope.cpp        2014-11-19 23:49:36 UTC (rev 176357)
</span><span class="lines">@@ -183,4 +183,10 @@
</span><span class="cx">     return m_scope-&gt;isActivationObject();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+JSValue DebuggerScope::caughtValue() const
+{
+    ASSERT(isCatchScope());
+    return reinterpret_cast&lt;JSNameScope*&gt;(m_scope.get())-&gt;value();
+}
+
</ins><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredebuggerDebuggerScopeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/debugger/DebuggerScope.h (176356 => 176357)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/debugger/DebuggerScope.h        2014-11-19 23:48:53 UTC (rev 176356)
+++ trunk/Source/JavaScriptCore/debugger/DebuggerScope.h        2014-11-19 23:49:36 UTC (rev 176357)
</span><span class="lines">@@ -90,6 +90,8 @@
</span><span class="cx">     bool isGlobalScope() const;
</span><span class="cx">     bool isFunctionOrEvalScope() const;
</span><span class="cx"> 
</span><ins>+    JSValue caughtValue() const;
+
</ins><span class="cx"> private:
</span><span class="cx">     JS_EXPORT_PRIVATE DebuggerScope(VM&amp;, JSScope*);
</span><span class="cx">     JS_EXPORT_PRIVATE void finishCreation(VM&amp;);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorInjectedScriptcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/InjectedScript.cpp (176356 => 176357)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/InjectedScript.cpp        2014-11-19 23:48:53 UTC (rev 176356)
+++ trunk/Source/JavaScriptCore/inspector/InjectedScript.cpp        2014-11-19 23:49:36 UTC (rev 176357)
</span><span class="lines">@@ -202,6 +202,23 @@
</span><span class="cx">     return BindingTraits&lt;Inspector::Protocol::Runtime::RemoteObject&gt;::runtimeCast(resultObject);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void InjectedScript::setExceptionValue(const Deprecated::ScriptValue&amp; value)
+{
+    ASSERT(!hasNoValue());
+    Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral(&quot;setExceptionValue&quot;), inspectorEnvironment()-&gt;functionCallHandler());
+    function.appendArgument(value);
+    RefPtr&lt;InspectorValue&gt; result;
+    makeCall(function, &amp;result);
+}
+
+void InjectedScript::clearExceptionValue()
+{
+    ASSERT(!hasNoValue());
+    Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral(&quot;clearExceptionValue&quot;), inspectorEnvironment()-&gt;functionCallHandler());
+    RefPtr&lt;InspectorValue&gt; result;
+    makeCall(function, &amp;result);
+}
+
</ins><span class="cx"> Deprecated::ScriptValue InjectedScript::findObjectById(const String&amp; objectId) const
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!hasNoValue());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorInjectedScripth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/InjectedScript.h (176356 => 176357)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/InjectedScript.h        2014-11-19 23:48:53 UTC (rev 176356)
+++ trunk/Source/JavaScriptCore/inspector/InjectedScript.h        2014-11-19 23:49:36 UTC (rev 176357)
</span><span class="lines">@@ -66,6 +66,9 @@
</span><span class="cx">     PassRefPtr&lt;Protocol::Runtime::RemoteObject&gt; wrapObject(const Deprecated::ScriptValue&amp;, const String&amp; groupName, bool generatePreview = false) const;
</span><span class="cx">     PassRefPtr&lt;Protocol::Runtime::RemoteObject&gt; wrapTable(const Deprecated::ScriptValue&amp; table, const Deprecated::ScriptValue&amp; columns) const;
</span><span class="cx"> 
</span><ins>+    void setExceptionValue(const Deprecated::ScriptValue&amp;);
+    void clearExceptionValue();
+
</ins><span class="cx">     Deprecated::ScriptValue findObjectById(const String&amp; objectId) const;
</span><span class="cx">     void inspectObject(Deprecated::ScriptValue);
</span><span class="cx">     void releaseObject(const String&amp; objectId);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorInjectedScriptManagercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/InjectedScriptManager.cpp (176356 => 176357)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/InjectedScriptManager.cpp        2014-11-19 23:48:53 UTC (rev 176356)
+++ trunk/Source/JavaScriptCore/inspector/InjectedScriptManager.cpp        2014-11-19 23:49:36 UTC (rev 176357)
</span><span class="lines">@@ -118,10 +118,16 @@
</span><span class="cx"> 
</span><span class="cx"> void InjectedScriptManager::releaseObjectGroup(const String&amp; objectGroup)
</span><span class="cx"> {
</span><del>-    for (auto it = m_idToInjectedScript.begin(); it != m_idToInjectedScript.end(); ++it)
-        it-&gt;value.releaseObjectGroup(objectGroup);
</del><ins>+    for (auto&amp; injectedScript : m_idToInjectedScript.values())
+        injectedScript.releaseObjectGroup(objectGroup);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void InjectedScriptManager::clearExceptionValue()
+{
+    for (auto&amp; injectedScript : m_idToInjectedScript.values())
+        injectedScript.clearExceptionValue();
+}
+
</ins><span class="cx"> String InjectedScriptManager::injectedScriptSource()
</span><span class="cx"> {
</span><span class="cx">     return StringImpl::createWithoutCopying(InjectedScriptSource_js, sizeof(InjectedScriptSource_js));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorInjectedScriptManagerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/InjectedScriptManager.h (176356 => 176357)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/InjectedScriptManager.h        2014-11-19 23:48:53 UTC (rev 176356)
+++ trunk/Source/JavaScriptCore/inspector/InjectedScriptManager.h        2014-11-19 23:49:36 UTC (rev 176357)
</span><span class="lines">@@ -66,6 +66,7 @@
</span><span class="cx">     InjectedScript injectedScriptForObjectId(const String&amp; objectId);
</span><span class="cx">     void discardInjectedScripts();
</span><span class="cx">     void releaseObjectGroup(const String&amp; objectGroup);
</span><ins>+    void clearExceptionValue();
</ins><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="cx">     virtual void didCreateInjectedScript(InjectedScript);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorInjectedScriptSourcejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/InjectedScriptSource.js (176356 => 176357)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/InjectedScriptSource.js        2014-11-19 23:48:53 UTC (rev 176356)
+++ trunk/Source/JavaScriptCore/inspector/InjectedScriptSource.js        2014-11-19 23:49:36 UTC (rev 176357)
</span><span class="lines">@@ -86,6 +86,16 @@
</span><span class="cx">         return this._fallbackWrapper(object);
</span><span class="cx">     },
</span><span class="cx"> 
</span><ins>+    setExceptionValue: function(value)
+    {
+        this._exceptionValue = value;
+    },
+
+    clearExceptionValue: function()
+    {
+        delete this._exceptionValue;
+    },
+
</ins><span class="cx">     /**
</span><span class="cx">      * @param {*} object
</span><span class="cx">      * @return {!RuntimeAgent.RemoteObject}
</span><span class="lines">@@ -1041,6 +1051,7 @@
</span><span class="cx"> function BasicCommandLineAPI()
</span><span class="cx"> {
</span><span class="cx">     this.$_ = injectedScript._lastResult;
</span><ins>+    this.$exception = injectedScript._exceptionValue;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> return injectedScript;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorScriptDebugServercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp (176356 => 176357)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp        2014-11-19 23:48:53 UTC (rev 176356)
+++ trunk/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp        2014-11-19 23:49:36 UTC (rev 176357)
</span><span class="lines">@@ -138,8 +138,8 @@
</span><span class="cx">     JSC::ExecState* state = globalObject-&gt;globalExec();
</span><span class="cx">     RefPtr&lt;JavaScriptCallFrame&gt; javaScriptCallFrame = JavaScriptCallFrame::create(debuggerCallFrame);
</span><span class="cx">     JSValue jsCallFrame = toJS(state, globalObject, javaScriptCallFrame.get());
</span><del>-    Deprecated::ScriptValue exception = reasonForPause() == PausedForException ? Deprecated::ScriptValue(state-&gt;vm(), currentException()) : Deprecated::ScriptValue();
-    listener-&gt;didPause(state, Deprecated::ScriptValue(state-&gt;vm(), jsCallFrame), exception);
</del><ins>+
+    listener-&gt;didPause(state, Deprecated::ScriptValue(state-&gt;vm(), jsCallFrame), exceptionOrCaughtValue(state));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ScriptDebugServer::dispatchBreakpointActionLog(ExecState* exec, const String&amp; message)
</span><span class="lines">@@ -327,6 +327,22 @@
</span><span class="cx">     return emptyActionVector;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Deprecated::ScriptValue ScriptDebugServer::exceptionOrCaughtValue(JSC::ExecState* state)
+{
+    if (reasonForPause() == PausedForException)
+        return Deprecated::ScriptValue(state-&gt;vm(), currentException());
+
+    RefPtr&lt;DebuggerCallFrame&gt; debuggerCallFrame = currentDebuggerCallFrame();
+    while (debuggerCallFrame) {
+        DebuggerScope* scope = debuggerCallFrame-&gt;scope();
+        if (scope-&gt;isCatchScope())
+            return Deprecated::ScriptValue(state-&gt;vm(), scope-&gt;caughtValue());
+        debuggerCallFrame = debuggerCallFrame-&gt;callerFrame();
+    }
+
+    return Deprecated::ScriptValue();
+}
+
</ins><span class="cx"> } // namespace Inspector
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(INSPECTOR)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorScriptDebugServerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/ScriptDebugServer.h (176356 => 176357)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/ScriptDebugServer.h        2014-11-19 23:48:53 UTC (rev 176356)
+++ trunk/Source/JavaScriptCore/inspector/ScriptDebugServer.h        2014-11-19 23:49:36 UTC (rev 176357)
</span><span class="lines">@@ -105,6 +105,8 @@
</span><span class="cx">     virtual void handlePause(JSC::Debugger::ReasonForPause, JSC::JSGlobalObject*) override final;
</span><span class="cx">     virtual void notifyDoneProcessingDebuggerEvents() override final;
</span><span class="cx"> 
</span><ins>+    Deprecated::ScriptValue exceptionOrCaughtValue(JSC::ExecState*);
+
</ins><span class="cx">     unsigned m_hitCount;
</span><span class="cx">     bool m_callingListeners;
</span><span class="cx">     BreakpointIDToActionsMap m_breakpointIDToActions;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectoragentsInspectorDebuggerAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.cpp (176356 => 176357)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.cpp        2014-11-19 23:48:53 UTC (rev 176356)
+++ trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.cpp        2014-11-19 23:49:36 UTC (rev 176357)
</span><span class="lines">@@ -65,6 +65,7 @@
</span><span class="cx">     , m_continueToLocationBreakpointID(JSC::noBreakpointID)
</span><span class="cx">     , m_enabled(false)
</span><span class="cx">     , m_javaScriptPauseScheduled(false)
</span><ins>+    , m_hasExceptionValue(false)
</ins><span class="cx">     , m_nextProbeSampleId(1)
</span><span class="cx"> {
</span><span class="cx">     // FIXME: make breakReason optional so that there was no need to init it with &quot;other&quot;.
</span><span class="lines">@@ -468,7 +469,6 @@
</span><span class="cx">     if (!assertPaused(errorString))
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    m_injectedScriptManager-&gt;releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup);
</del><span class="cx">     scriptDebugServer().continueProgram();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -477,7 +477,6 @@
</span><span class="cx">     if (!assertPaused(errorString))
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    m_injectedScriptManager-&gt;releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup);
</del><span class="cx">     scriptDebugServer().stepOverStatement();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -486,7 +485,6 @@
</span><span class="cx">     if (!assertPaused(errorString))
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    m_injectedScriptManager-&gt;releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup);
</del><span class="cx">     scriptDebugServer().stepIntoStatement();
</span><span class="cx"> 
</span><span class="cx">     if (m_listener)
</span><span class="lines">@@ -498,7 +496,6 @@
</span><span class="cx">     if (!assertPaused(errorString))
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    m_injectedScriptManager-&gt;releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup);
</del><span class="cx">     scriptDebugServer().stepOutOfFunction();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -643,6 +640,8 @@
</span><span class="cx">             m_breakReason = InspectorDebuggerFrontendDispatcher::Reason::Exception;
</span><span class="cx">             m_breakAuxData = injectedScript.wrapObject(exception, InspectorDebuggerAgent::backtraceObjectGroup)-&gt;openAccessors();
</span><span class="cx">             // m_breakAuxData might be null after this.
</span><ins>+            injectedScript.setExceptionValue(exception);
+            m_hasExceptionValue = true;
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -687,8 +686,10 @@
</span><span class="cx"> {
</span><span class="cx">     m_pausedScriptState = nullptr;
</span><span class="cx">     m_currentCallStack = Deprecated::ScriptValue();
</span><ins>+    m_injectedScriptManager-&gt;releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup);
</ins><span class="cx">     m_injectedScriptManager-&gt;inspectorEnvironment().executionStopwatch()-&gt;start();
</span><span class="cx">     clearBreakDetails();
</span><ins>+    clearExceptionValue();
</ins><span class="cx"> 
</span><span class="cx">     m_frontendDispatcher-&gt;resumed();
</span><span class="cx"> }
</span><span class="lines">@@ -724,6 +725,7 @@
</span><span class="cx">     m_continueToLocationBreakpointID = JSC::noBreakpointID;
</span><span class="cx">     clearBreakDetails();
</span><span class="cx">     m_javaScriptPauseScheduled = false;
</span><ins>+    m_hasExceptionValue = false;
</ins><span class="cx"> 
</span><span class="cx">     scriptDebugServer().continueProgram();
</span><span class="cx"> }
</span><span class="lines">@@ -754,6 +756,14 @@
</span><span class="cx">     m_breakAuxData = nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void InspectorDebuggerAgent::clearExceptionValue()
+{
+    if (m_hasExceptionValue) {
+        m_injectedScriptManager-&gt;clearExceptionValue();
+        m_hasExceptionValue = false;
+    }
+}
+
</ins><span class="cx"> } // namespace Inspector
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(INSPECTOR)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectoragentsInspectorDebuggerAgenth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.h (176356 => 176357)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.h        2014-11-19 23:48:53 UTC (rev 176356)
+++ trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.h        2014-11-19 23:49:36 UTC (rev 176357)
</span><span class="lines">@@ -146,6 +146,7 @@
</span><span class="cx">     void clearDebuggerBreakpointState();
</span><span class="cx">     void clearInspectorBreakpointState();
</span><span class="cx">     void clearBreakDetails();
</span><ins>+    void clearExceptionValue();
</ins><span class="cx"> 
</span><span class="cx">     bool breakpointActionsFromProtocol(ErrorString&amp;, RefPtr&lt;InspectorArray&gt;&amp; actions, BreakpointActions* result);
</span><span class="cx"> 
</span><span class="lines">@@ -167,6 +168,7 @@
</span><span class="cx">     RefPtr&lt;InspectorObject&gt; m_breakAuxData;
</span><span class="cx">     bool m_enabled;
</span><span class="cx">     bool m_javaScriptPauseScheduled;
</span><ins>+    bool m_hasExceptionValue;
</ins><span class="cx">     RefPtr&lt;WTF::Stopwatch&gt; m_stopwatch;
</span><span class="cx">     int m_nextProbeSampleId;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSNameScopeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSNameScope.h (176356 => 176357)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSNameScope.h        2014-11-19 23:48:53 UTC (rev 176356)
+++ trunk/Source/JavaScriptCore/runtime/JSNameScope.h        2014-11-19 23:49:36 UTC (rev 176357)
</span><span class="lines">@@ -65,9 +65,11 @@
</span><span class="cx"> 
</span><span class="cx">     DECLARE_INFO;
</span><span class="cx"> 
</span><del>-    bool isFunctionNameScope() { return m_type == FunctionNameScope; }
-    bool isCatchScope() { return m_type == CatchScope; }
</del><ins>+    bool isFunctionNameScope() const { return m_type == FunctionNameScope; }
+    bool isCatchScope() const { return m_type == CatchScope; }
</ins><span class="cx"> 
</span><ins>+    JSValue value() const { return m_registerStore.get(); }
+
</ins><span class="cx"> protected:
</span><span class="cx">     void finishCreation(VM&amp; vm, const Identifier&amp; identifier, JSValue value, unsigned attributes)
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (176356 => 176357)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-11-19 23:48:53 UTC (rev 176356)
+++ trunk/Source/WebCore/ChangeLog        2014-11-19 23:49:36 UTC (rev 176357)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2014-11-19  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
+
+        Web Inspector: Provide $exception in the console for the thrown exception value
+        https://bugs.webkit.org/show_bug.cgi?id=138726
+
+        Reviewed by Timothy Hatcher.
+
+        Tests: inspector/debugger/command-line-api-exception-nested-catch.html
+               inspector/debugger/command-line-api-exception.html
+
+        * inspector/CommandLineAPIModuleSource.js:
+        Expose $exception in the more complete command line API.
+
</ins><span class="cx"> 2014-11-19  David Hyatt  &lt;hyatt@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Images/replaced elements that are as tall as a page should be on their own page
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorCommandLineAPIModuleSourcejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/CommandLineAPIModuleSource.js (176356 => 176357)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/CommandLineAPIModuleSource.js        2014-11-19 23:48:53 UTC (rev 176356)
+++ trunk/Source/WebCore/inspector/CommandLineAPIModuleSource.js        2014-11-19 23:49:36 UTC (rev 176357)
</span><span class="lines">@@ -124,6 +124,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     this.$_ = injectedScript._lastResult;
</span><ins>+    this.$exception = injectedScript._exceptionValue;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> /**
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (176356 => 176357)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2014-11-19 23:48:53 UTC (rev 176356)
+++ trunk/Source/WebInspectorUI/ChangeLog        2014-11-19 23:49:36 UTC (rev 176357)
</span><span class="lines">@@ -1,5 +1,20 @@
</span><span class="cx"> 2014-11-19  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Web Inspector: Provide $exception in the console for the thrown exception value
+        https://bugs.webkit.org/show_bug.cgi?id=138726
+
+        Reviewed by Timothy Hatcher.
+
+        * UserInterface/Base/Test.js:
+        (WebInspector.loaded):
+        In order to use RuntimeManager to execute in the global context or on the
+        active debugger call frame, we need to expose the quickConsole controller.
+
+        * UserInterface/Controllers/JavaScriptRuntimeCompletionProvider.js:
+        Expose $exception to completion when we paused because of an exception.
+
+2014-11-19  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
+
</ins><span class="cx">         Web Inspector: Debugger should not mutate variable when hovering mouse over ++n expression
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=138839
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceBaseTestjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Base/Test.js (176356 => 176357)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Base/Test.js        2014-11-19 23:48:53 UTC (rev 176356)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/Test.js        2014-11-19 23:49:36 UTC (rev 176357)
</span><span class="lines">@@ -56,6 +56,9 @@
</span><span class="cx">     this.probeManager = new WebInspector.ProbeManager;
</span><span class="cx">     this.replayManager = new WebInspector.ReplayManager;
</span><span class="cx"> 
</span><ins>+    // Global controllers.
+    this.quickConsole = {executionContextIdentifier: undefined};
+
</ins><span class="cx">     document.addEventListener(&quot;DOMContentLoaded&quot;, this.contentLoaded.bind(this));
</span><span class="cx"> 
</span><span class="cx">     // Enable agents.
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceControllersJavaScriptRuntimeCompletionProviderjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/JavaScriptRuntimeCompletionProvider.js (176356 => 176357)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Controllers/JavaScriptRuntimeCompletionProvider.js        2014-11-19 23:48:53 UTC (rev 176356)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/JavaScriptRuntimeCompletionProvider.js        2014-11-19 23:49:36 UTC (rev 176357)
</span><span class="lines">@@ -174,7 +174,9 @@
</span><span class="cx">             RuntimeAgent.releaseObjectGroup(&quot;completion&quot;);
</span><span class="cx"> 
</span><span class="cx">             if (!base) {
</span><del>-                const commandLineAPI = [&quot;$&quot;, &quot;$$&quot;, &quot;$x&quot;, &quot;dir&quot;, &quot;dirxml&quot;, &quot;keys&quot;, &quot;values&quot;, &quot;profile&quot;, &quot;profileEnd&quot;, &quot;monitorEvents&quot;, &quot;unmonitorEvents&quot;, &quot;inspect&quot;, &quot;copy&quot;, &quot;clear&quot;, &quot;getEventListeners&quot;, &quot;$0&quot;, &quot;$1&quot;, &quot;$2&quot;, &quot;$3&quot;, &quot;$4&quot;, &quot;$_&quot;];
</del><ins>+                var commandLineAPI = [&quot;$&quot;, &quot;$$&quot;, &quot;$x&quot;, &quot;dir&quot;, &quot;dirxml&quot;, &quot;keys&quot;, &quot;values&quot;, &quot;profile&quot;, &quot;profileEnd&quot;, &quot;monitorEvents&quot;, &quot;unmonitorEvents&quot;, &quot;inspect&quot;, &quot;copy&quot;, &quot;clear&quot;, &quot;getEventListeners&quot;, &quot;$0&quot;, &quot;$1&quot;, &quot;$2&quot;, &quot;$3&quot;, &quot;$4&quot;, &quot;$_&quot;];
+                if (WebInspector.debuggerManager.paused &amp;&amp; WebInspector.debuggerManager.pauseReason === WebInspector.DebuggerManager.PauseReason.Exception)
+                    commandLineAPI.push(&quot;$exception&quot;);
</ins><span class="cx">                 for (var i = 0; i &lt; commandLineAPI.length; ++i)
</span><span class="cx">                     propertyNames[commandLineAPI[i]] = true;
</span><span class="cx">             }
</span></span></pre>
</div>
</div>

</body>
</html>