<!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>[164824] trunk/Source</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/164824">164824</a></dd>
<dt>Author</dt> <dd>joepeck@webkit.org</dd>
<dt>Date</dt> <dd>2014-02-27 12:45:08 -0800 (Thu, 27 Feb 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Web Inspector: JSContext inspection should report exceptions in the console
https://bugs.webkit.org/show_bug.cgi?id=128776

Reviewed by Timothy Hatcher.

Source/JavaScriptCore:

When JavaScript API functions have an exception, let the inspector
know so it can log the JavaScript and Native backtrace that caused
the exception.

Include some clean up of ConsoleMessage and ScriptCallStack construction.

* API/JSBase.cpp:
(JSEvaluateScript):
(JSCheckScriptSyntax):
* API/JSObjectRef.cpp:
(JSObjectMakeFunction):
(JSObjectMakeArray):
(JSObjectMakeDate):
(JSObjectMakeError):
(JSObjectMakeRegExp):
(JSObjectGetProperty):
(JSObjectSetProperty):
(JSObjectGetPropertyAtIndex):
(JSObjectSetPropertyAtIndex):
(JSObjectDeleteProperty):
(JSObjectCallAsFunction):
(JSObjectCallAsConstructor):
* API/JSValue.mm:
(reportExceptionToInspector):
(valueToArray):
(valueToDictionary):
* API/JSValueRef.cpp:
(JSValueIsEqual):
(JSValueIsInstanceOfConstructor):
(JSValueCreateJSONString):
(JSValueToNumber):
(JSValueToStringCopy):
(JSValueToObject):
When seeing an exception, let the inspector know there was an exception.

* inspector/JSGlobalObjectInspectorController.h:
* inspector/JSGlobalObjectInspectorController.cpp:
(Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
(Inspector::JSGlobalObjectInspectorController::appendAPIBacktrace):
(Inspector::JSGlobalObjectInspectorController::reportAPIException):
Log API exceptions by also grabbing the native backtrace.

* inspector/ScriptCallStack.h:
* inspector/ScriptCallStack.cpp:
(Inspector::ScriptCallStack::firstNonNativeCallFrame):
(Inspector::ScriptCallStack::append):
Minor extensions to ScriptCallStack to make it easier to work with.

* inspector/ConsoleMessage.cpp:
(Inspector::ConsoleMessage::ConsoleMessage):
(Inspector::ConsoleMessage::autogenerateMetadata):
Provide better default information if the first call frame was native.

* inspector/ScriptCallStackFactory.cpp:
(Inspector::createScriptCallStack):
(Inspector::extractSourceInformationFromException):
(Inspector::createScriptCallStackFromException):
Perform the handling here of inserting a fake call frame for exceptions
if there was no call stack (e.g. a SyntaxError) or if the first call
frame had no information.

* inspector/ConsoleMessage.cpp:
(Inspector::ConsoleMessage::ConsoleMessage):
(Inspector::ConsoleMessage::autogenerateMetadata):
* inspector/ConsoleMessage.h:
* inspector/ScriptCallStackFactory.cpp:
(Inspector::createScriptCallStack):
(Inspector::createScriptCallStackForConsole):
* inspector/ScriptCallStackFactory.h:
* inspector/agents/InspectorConsoleAgent.cpp:
(Inspector::InspectorConsoleAgent::enable):
(Inspector::InspectorConsoleAgent::addMessageToConsole):
(Inspector::InspectorConsoleAgent::count):
* inspector/agents/JSGlobalObjectDebuggerAgent.cpp:
(Inspector::JSGlobalObjectDebuggerAgent::breakpointActionLog):
ConsoleMessage cleanup.

Source/WebCore:

Include some clean up of ConsoleMessage and ScriptCallStack construction.

Covered by existing tests.

* bindings/js/JSDOMBinding.cpp:
(WebCore::reportException):
Simplify code now that createStackTraceFromException handles it.

* page/ContentSecurityPolicy.cpp:
(WebCore::gatherSecurityPolicyViolationEventData):
(WebCore::ContentSecurityPolicy::reportViolation):
ScriptCallStack can give us the first non-native callframe.

* inspector/InspectorResourceAgent.cpp:
(WebCore::InspectorResourceAgent::buildInitiatorObject):
* inspector/PageDebuggerAgent.cpp:
(WebCore::PageDebuggerAgent::breakpointActionLog):
* inspector/TimelineRecordFactory.cpp:
(WebCore::TimelineRecordFactory::createGenericRecord):
* page/Console.cpp:
(WebCore::internalAddMessage):
(WebCore::Console::profile):
(WebCore::Console::profileEnd):
(WebCore::Console::timeEnd):
* page/ContentSecurityPolicy.cpp:
(WebCore::gatherSecurityPolicyViolationEventData):
(WebCore::ContentSecurityPolicy::reportViolation):
* page/DOMWindow.cpp:
(WebCore::DOMWindow::postMessage):

Source/WebInspectorUI:

* UserInterface/ConsoleMessageImpl.js:
(WebInspector.ConsoleMessageImpl.prototype._formatMessage):
(WebInspector.ConsoleMessageImpl.prototype._shouldHideURL):
(WebInspector.ConsoleMessageImpl.prototype._firstNonNativeCallFrame):
(WebInspector.ConsoleMessageImpl.prototype._populateStackTraceTreeElement):
Provide better handling for &quot;[native code]&quot; and legacy &quot;undefined&quot;
call frame URLs. Never linkify these. Also, when showing a link
for an exception, always use the first non-native call frame as
the link location.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreAPIJSBasecpp">trunk/Source/JavaScriptCore/API/JSBase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreAPIJSObjectRefcpp">trunk/Source/JavaScriptCore/API/JSObjectRef.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreAPIJSValuemm">trunk/Source/JavaScriptCore/API/JSValue.mm</a></li>
<li><a href="#trunkSourceJavaScriptCoreAPIJSValueRefcpp">trunk/Source/JavaScriptCore/API/JSValueRef.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorConsoleMessagecpp">trunk/Source/JavaScriptCore/inspector/ConsoleMessage.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorConsoleMessageh">trunk/Source/JavaScriptCore/inspector/ConsoleMessage.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorJSGlobalObjectInspectorControllercpp">trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorJSGlobalObjectInspectorControllerh">trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorScriptCallStackcpp">trunk/Source/JavaScriptCore/inspector/ScriptCallStack.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorScriptCallStackh">trunk/Source/JavaScriptCore/inspector/ScriptCallStack.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorScriptCallStackFactorycpp">trunk/Source/JavaScriptCore/inspector/ScriptCallStackFactory.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorScriptCallStackFactoryh">trunk/Source/JavaScriptCore/inspector/ScriptCallStackFactory.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectoragentsInspectorConsoleAgentcpp">trunk/Source/JavaScriptCore/inspector/agents/InspectorConsoleAgent.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectoragentsJSGlobalObjectDebuggerAgentcpp">trunk/Source/JavaScriptCore/inspector/agents/JSGlobalObjectDebuggerAgent.cpp</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMBindingcpp">trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorResourceAgentcpp">trunk/Source/WebCore/inspector/InspectorResourceAgent.cpp</a></li>
<li><a href="#trunkSourceWebCoreinspectorPageDebuggerAgentcpp">trunk/Source/WebCore/inspector/PageDebuggerAgent.cpp</a></li>
<li><a href="#trunkSourceWebCoreinspectorTimelineRecordFactorycpp">trunk/Source/WebCore/inspector/TimelineRecordFactory.cpp</a></li>
<li><a href="#trunkSourceWebCorepageConsolecpp">trunk/Source/WebCore/page/Console.cpp</a></li>
<li><a href="#trunkSourceWebCorepageContentSecurityPolicycpp">trunk/Source/WebCore/page/ContentSecurityPolicy.cpp</a></li>
<li><a href="#trunkSourceWebCorepageDOMWindowcpp">trunk/Source/WebCore/page/DOMWindow.cpp</a></li>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsConsoleMessageImpljs">trunk/Source/WebInspectorUI/UserInterface/Views/ConsoleMessageImpl.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreAPIJSBasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/API/JSBase.cpp (164823 => 164824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/API/JSBase.cpp        2014-02-27 20:37:51 UTC (rev 164823)
+++ trunk/Source/JavaScriptCore/API/JSBase.cpp        2014-02-27 20:45:08 UTC (rev 164824)
</span><span class="lines">@@ -40,6 +40,10 @@
</span><span class="cx"> #include &quot;SourceCode.h&quot;
</span><span class="cx"> #include &lt;wtf/text/StringHash.h&gt;
</span><span class="cx"> 
</span><ins>+#if ENABLE(REMOTE_INSPECTOR)
+#include &quot;JSGlobalObjectInspectorController.h&quot;
+#endif
+
</ins><span class="cx"> using namespace JSC;
</span><span class="cx"> 
</span><span class="cx"> JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef thisObject, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception)
</span><span class="lines">@@ -65,6 +69,14 @@
</span><span class="cx">     if (evaluationException) {
</span><span class="cx">         if (exception)
</span><span class="cx">             *exception = toRef(exec, evaluationException);
</span><ins>+#if ENABLE(REMOTE_INSPECTOR)
+        // FIXME: If we have a debugger attached we could learn about ParseError exceptions through
+        // ScriptDebugServer::sourceParsed and this path could produce a duplicate warning. The
+        // Debugger path is currently ignored by inspector.
+        // NOTE: If we don't have a debugger, this SourceCode will be forever lost to the inspector.
+        // We could stash it in the inspector in case an inspector is ever opened.
+        globalObject-&gt;inspectorController().reportAPIException(exec, evaluationException);
+#endif
</ins><span class="cx">         return 0;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -94,6 +106,9 @@
</span><span class="cx">     if (!isValidSyntax) {
</span><span class="cx">         if (exception)
</span><span class="cx">             *exception = toRef(exec, syntaxException);
</span><ins>+#if ENABLE(REMOTE_INSPECTOR)
+        exec-&gt;vmEntryGlobalObject()-&gt;inspectorController().reportAPIException(exec, syntaxException);
+#endif
</ins><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreAPIJSObjectRefcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/API/JSObjectRef.cpp (164823 => 164824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/API/JSObjectRef.cpp        2014-02-27 20:37:51 UTC (rev 164823)
+++ trunk/Source/JavaScriptCore/API/JSObjectRef.cpp        2014-02-27 20:45:08 UTC (rev 164824)
</span><span class="lines">@@ -55,6 +55,10 @@
</span><span class="cx"> #include &quot;PropertyNameArray.h&quot;
</span><span class="cx"> #include &quot;RegExpConstructor.h&quot;
</span><span class="cx"> 
</span><ins>+#if ENABLE(REMOTE_INSPECTOR)
+#include &quot;JSGlobalObjectInspectorController.h&quot;
+#endif
+
</ins><span class="cx"> using namespace JSC;
</span><span class="cx"> 
</span><span class="cx"> JSClassRef JSClassCreate(const JSClassDefinition* definition)
</span><span class="lines">@@ -145,9 +149,13 @@
</span><span class="cx"> 
</span><span class="cx">     JSObject* result = constructFunction(exec, exec-&gt;lexicalGlobalObject(), args, nameID, sourceURL-&gt;string(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()));
</span><span class="cx">     if (exec-&gt;hadException()) {
</span><ins>+        JSValue exceptionValue = exec-&gt;exception();
</ins><span class="cx">         if (exception)
</span><del>-            *exception = toRef(exec, exec-&gt;exception());
</del><ins>+            *exception = toRef(exec, exceptionValue);
</ins><span class="cx">         exec-&gt;clearException();
</span><ins>+#if ENABLE(REMOTE_INSPECTOR)
+        exec-&gt;vmEntryGlobalObject()-&gt;inspectorController().reportAPIException(exec, exceptionValue);
+#endif
</ins><span class="cx">         result = 0;
</span><span class="cx">     }
</span><span class="cx">     return toRef(result);
</span><span class="lines">@@ -173,9 +181,13 @@
</span><span class="cx">         result = constructEmptyArray(exec, 0);
</span><span class="cx"> 
</span><span class="cx">     if (exec-&gt;hadException()) {
</span><ins>+        JSValue exceptionValue = exec-&gt;exception();
</ins><span class="cx">         if (exception)
</span><del>-            *exception = toRef(exec, exec-&gt;exception());
</del><ins>+            *exception = toRef(exec, exceptionValue);
</ins><span class="cx">         exec-&gt;clearException();
</span><ins>+#if ENABLE(REMOTE_INSPECTOR)
+        exec-&gt;vmEntryGlobalObject()-&gt;inspectorController().reportAPIException(exec, exceptionValue);
+#endif
</ins><span class="cx">         result = 0;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -197,9 +209,13 @@
</span><span class="cx"> 
</span><span class="cx">     JSObject* result = constructDate(exec, exec-&gt;lexicalGlobalObject(), argList);
</span><span class="cx">     if (exec-&gt;hadException()) {
</span><ins>+        JSValue exceptionValue = exec-&gt;exception();
</ins><span class="cx">         if (exception)
</span><del>-            *exception = toRef(exec, exec-&gt;exception());
</del><ins>+            *exception = toRef(exec, exceptionValue);
</ins><span class="cx">         exec-&gt;clearException();
</span><ins>+#if ENABLE(REMOTE_INSPECTOR)
+        exec-&gt;vmEntryGlobalObject()-&gt;inspectorController().reportAPIException(exec, exceptionValue);
+#endif
</ins><span class="cx">         result = 0;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -220,9 +236,13 @@
</span><span class="cx">     JSObject* result = ErrorInstance::create(exec, errorStructure, message);
</span><span class="cx"> 
</span><span class="cx">     if (exec-&gt;hadException()) {
</span><ins>+        JSValue exceptionValue = exec-&gt;exception();
</ins><span class="cx">         if (exception)
</span><del>-            *exception = toRef(exec, exec-&gt;exception());
</del><ins>+            *exception = toRef(exec, exceptionValue);
</ins><span class="cx">         exec-&gt;clearException();
</span><ins>+#if ENABLE(REMOTE_INSPECTOR)
+        exec-&gt;vmEntryGlobalObject()-&gt;inspectorController().reportAPIException(exec, exceptionValue);
+#endif
</ins><span class="cx">         result = 0;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -244,9 +264,13 @@
</span><span class="cx"> 
</span><span class="cx">     JSObject* result = constructRegExp(exec, exec-&gt;lexicalGlobalObject(),  argList);
</span><span class="cx">     if (exec-&gt;hadException()) {
</span><ins>+        JSValue exceptionValue = exec-&gt;exception();
</ins><span class="cx">         if (exception)
</span><del>-            *exception = toRef(exec, exec-&gt;exception());
</del><ins>+            *exception = toRef(exec, exceptionValue);
</ins><span class="cx">         exec-&gt;clearException();
</span><ins>+#if ENABLE(REMOTE_INSPECTOR)
+        exec-&gt;vmEntryGlobalObject()-&gt;inspectorController().reportAPIException(exec, exceptionValue);
+#endif
</ins><span class="cx">         result = 0;
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -308,9 +332,13 @@
</span><span class="cx"> 
</span><span class="cx">     JSValue jsValue = jsObject-&gt;get(exec, propertyName-&gt;identifier(&amp;exec-&gt;vm()));
</span><span class="cx">     if (exec-&gt;hadException()) {
</span><ins>+        JSValue exceptionValue = exec-&gt;exception();
</ins><span class="cx">         if (exception)
</span><del>-            *exception = toRef(exec, exec-&gt;exception());
</del><ins>+            *exception = toRef(exec, exceptionValue);
</ins><span class="cx">         exec-&gt;clearException();
</span><ins>+#if ENABLE(REMOTE_INSPECTOR)
+        exec-&gt;vmEntryGlobalObject()-&gt;inspectorController().reportAPIException(exec, exceptionValue);
+#endif
</ins><span class="cx">     }
</span><span class="cx">     return toRef(exec, jsValue);
</span><span class="cx"> }
</span><span class="lines">@@ -337,9 +365,13 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (exec-&gt;hadException()) {
</span><ins>+        JSValue exceptionValue = exec-&gt;exception();
</ins><span class="cx">         if (exception)
</span><del>-            *exception = toRef(exec, exec-&gt;exception());
</del><ins>+            *exception = toRef(exec, exceptionValue);
</ins><span class="cx">         exec-&gt;clearException();
</span><ins>+#if ENABLE(REMOTE_INSPECTOR)
+        exec-&gt;vmEntryGlobalObject()-&gt;inspectorController().reportAPIException(exec, exceptionValue);
+#endif
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -356,9 +388,13 @@
</span><span class="cx"> 
</span><span class="cx">     JSValue jsValue = jsObject-&gt;get(exec, propertyIndex);
</span><span class="cx">     if (exec-&gt;hadException()) {
</span><ins>+        JSValue exceptionValue = exec-&gt;exception();
</ins><span class="cx">         if (exception)
</span><del>-            *exception = toRef(exec, exec-&gt;exception());
</del><ins>+            *exception = toRef(exec, exceptionValue);
</ins><span class="cx">         exec-&gt;clearException();
</span><ins>+#if ENABLE(REMOTE_INSPECTOR)
+        exec-&gt;vmEntryGlobalObject()-&gt;inspectorController().reportAPIException(exec, exceptionValue);
+#endif
</ins><span class="cx">     }
</span><span class="cx">     return toRef(exec, jsValue);
</span><span class="cx"> }
</span><span class="lines">@@ -378,9 +414,13 @@
</span><span class="cx">     
</span><span class="cx">     jsObject-&gt;methodTable()-&gt;putByIndex(jsObject, exec, propertyIndex, jsValue, false);
</span><span class="cx">     if (exec-&gt;hadException()) {
</span><ins>+        JSValue exceptionValue = exec-&gt;exception();
</ins><span class="cx">         if (exception)
</span><del>-            *exception = toRef(exec, exec-&gt;exception());
</del><ins>+            *exception = toRef(exec, exceptionValue);
</ins><span class="cx">         exec-&gt;clearException();
</span><ins>+#if ENABLE(REMOTE_INSPECTOR)
+        exec-&gt;vmEntryGlobalObject()-&gt;inspectorController().reportAPIException(exec, exceptionValue);
+#endif
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -397,9 +437,13 @@
</span><span class="cx"> 
</span><span class="cx">     bool result = jsObject-&gt;methodTable()-&gt;deleteProperty(jsObject, exec, propertyName-&gt;identifier(&amp;exec-&gt;vm()));
</span><span class="cx">     if (exec-&gt;hadException()) {
</span><ins>+        JSValue exceptionValue = exec-&gt;exception();
</ins><span class="cx">         if (exception)
</span><del>-            *exception = toRef(exec, exec-&gt;exception());
</del><ins>+            *exception = toRef(exec, exceptionValue);
</ins><span class="cx">         exec-&gt;clearException();
</span><ins>+#if ENABLE(REMOTE_INSPECTOR)
+        exec-&gt;vmEntryGlobalObject()-&gt;inspectorController().reportAPIException(exec, exceptionValue);
+#endif
</ins><span class="cx">     }
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="lines">@@ -542,9 +586,13 @@
</span><span class="cx"> 
</span><span class="cx">     JSValueRef result = toRef(exec, call(exec, jsObject, callType, callData, jsThisObject, argList));
</span><span class="cx">     if (exec-&gt;hadException()) {
</span><ins>+        JSValue exceptionValue = exec-&gt;exception();
</ins><span class="cx">         if (exception)
</span><del>-            *exception = toRef(exec, exec-&gt;exception());
</del><ins>+            *exception = toRef(exec, exceptionValue);
</ins><span class="cx">         exec-&gt;clearException();
</span><ins>+#if ENABLE(REMOTE_INSPECTOR)
+        exec-&gt;vmEntryGlobalObject()-&gt;inspectorController().reportAPIException(exec, exceptionValue);
+#endif
</ins><span class="cx">         result = 0;
</span><span class="cx">     }
</span><span class="cx">     return result;
</span><span class="lines">@@ -579,9 +627,13 @@
</span><span class="cx">         argList.append(toJS(exec, arguments[i]));
</span><span class="cx">     JSObjectRef result = toRef(construct(exec, jsObject, constructType, constructData, argList));
</span><span class="cx">     if (exec-&gt;hadException()) {
</span><ins>+        JSValue exceptionValue = exec-&gt;exception();
</ins><span class="cx">         if (exception)
</span><del>-            *exception = toRef(exec, exec-&gt;exception());
</del><ins>+            *exception = toRef(exec, exceptionValue);
</ins><span class="cx">         exec-&gt;clearException();
</span><ins>+#if ENABLE(REMOTE_INSPECTOR)
+        exec-&gt;vmEntryGlobalObject()-&gt;inspectorController().reportAPIException(exec, exceptionValue);
+#endif
</ins><span class="cx">         result = 0;
</span><span class="cx">     }
</span><span class="cx">     return result;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreAPIJSValuemm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/API/JSValue.mm (164823 => 164824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/API/JSValue.mm        2014-02-27 20:37:51 UTC (rev 164823)
+++ trunk/Source/JavaScriptCore/API/JSValue.mm        2014-02-27 20:45:08 UTC (rev 164824)
</span><span class="lines">@@ -20,7 +20,7 @@
</span><span class="cx">  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
</span><span class="cx">  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
</span><span class="cx">  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
</span><del>- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
</del><ins>+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</ins><span class="cx">  */
</span><span class="cx"> 
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="lines">@@ -47,6 +47,12 @@
</span><span class="cx"> #import &lt;wtf/text/WTFString.h&gt;
</span><span class="cx"> #import &lt;wtf/text/StringHash.h&gt;
</span><span class="cx"> 
</span><ins>+#if ENABLE(REMOTE_INSPECTOR)
+#import &quot;CallFrame.h&quot;
+#import &quot;JSGlobalObject.h&quot;
+#import &quot;JSGlobalObjectInspectorController.h&quot;
+#endif
+
</ins><span class="cx"> #if JSC_OBJC_API_ENABLED
</span><span class="cx"> 
</span><span class="cx"> NSString * const JSPropertyDescriptorWritableKey = @&quot;writable&quot;;
</span><span class="lines">@@ -629,6 +635,14 @@
</span><span class="cx">     return last;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if ENABLE(REMOTE_INSPECTOR)
+static void reportExceptionToInspector(JSGlobalContextRef context, JSC::JSValue exception)
+{
+    JSC::ExecState* exec = toJS(context);
+    exec-&gt;vmEntryGlobalObject()-&gt;inspectorController().reportAPIException(exec, exception);
+}
+#endif
+
</ins><span class="cx"> static JSContainerConvertor::Task valueToObjectWithoutCopy(JSGlobalContextRef context, JSValueRef value)
</span><span class="cx"> {
</span><span class="cx">     if (!JSValueIsObject(context, value)) {
</span><span class="lines">@@ -783,8 +797,13 @@
</span><span class="cx">         return containerValueToObject(context, (JSContainerConvertor::Task){ value, [NSMutableArray array], ContainerArray});
</span><span class="cx"> 
</span><span class="cx">     JSC::APIEntryShim shim(toJS(context));
</span><del>-    if (!(JSValueIsNull(context, value) || JSValueIsUndefined(context, value)))
-        *exception = toRef(JSC::createTypeError(toJS(context), ASCIILiteral(&quot;Cannot convert primitive to NSArray&quot;)));
</del><ins>+    if (!(JSValueIsNull(context, value) || JSValueIsUndefined(context, value))) {
+        JSC::JSObject* exceptionObject = JSC::createTypeError(toJS(context), ASCIILiteral(&quot;Cannot convert primitive to NSArray&quot;));
+        *exception = toRef(exceptionObject);
+#if ENABLE(REMOTE_INSPECTOR)
+        reportExceptionToInspector(context, exceptionObject);
+#endif
+    }
</ins><span class="cx">     return nil;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -800,8 +819,13 @@
</span><span class="cx">         return containerValueToObject(context, (JSContainerConvertor::Task){ value, [NSMutableDictionary dictionary], ContainerDictionary});
</span><span class="cx"> 
</span><span class="cx">     JSC::APIEntryShim shim(toJS(context));
</span><del>-    if (!(JSValueIsNull(context, value) || JSValueIsUndefined(context, value)))
-        *exception = toRef(JSC::createTypeError(toJS(context), ASCIILiteral(&quot;Cannot convert primitive to NSDictionary&quot;)));
</del><ins>+    if (!(JSValueIsNull(context, value) || JSValueIsUndefined(context, value))) {
+        JSC::JSObject* exceptionObject = JSC::createTypeError(toJS(context), ASCIILiteral(&quot;Cannot convert primitive to NSDictionary&quot;));
+        *exception = toRef(exceptionObject);
+#if ENABLE(REMOTE_INSPECTOR)
+        reportExceptionToInspector(context, exceptionObject);
+#endif
+    }
</ins><span class="cx">     return nil;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreAPIJSValueRefcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/API/JSValueRef.cpp (164823 => 164824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/API/JSValueRef.cpp        2014-02-27 20:37:51 UTC (rev 164823)
+++ trunk/Source/JavaScriptCore/API/JSValueRef.cpp        2014-02-27 20:45:08 UTC (rev 164824)
</span><span class="lines">@@ -20,7 +20,7 @@
</span><span class="cx">  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
</span><span class="cx">  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
</span><span class="cx">  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
</span><del>- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
</del><ins>+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</ins><span class="cx">  */
</span><span class="cx"> 
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="lines">@@ -48,6 +48,10 @@
</span><span class="cx"> #include &lt;mach-o/dyld.h&gt;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if ENABLE(REMOTE_INSPECTOR)
+#include &quot;JSGlobalObjectInspectorController.h&quot;
+#endif
+
</ins><span class="cx"> using namespace JSC;
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(MAC)
</span><span class="lines">@@ -202,9 +206,13 @@
</span><span class="cx"> 
</span><span class="cx">     bool result = JSValue::equal(exec, jsA, jsB); // false if an exception is thrown
</span><span class="cx">     if (exec-&gt;hadException()) {
</span><ins>+        JSValue exceptionValue = exec-&gt;exception();
</ins><span class="cx">         if (exception)
</span><del>-            *exception = toRef(exec, exec-&gt;exception());
</del><ins>+            *exception = toRef(exec, exceptionValue);
</ins><span class="cx">         exec-&gt;clearException();
</span><ins>+#if ENABLE(REMOTE_INSPECTOR)
+        exec-&gt;vmEntryGlobalObject()-&gt;inspectorController().reportAPIException(exec, exceptionValue);
+#endif
</ins><span class="cx">     }
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="lines">@@ -240,9 +248,13 @@
</span><span class="cx">         return false;
</span><span class="cx">     bool result = jsConstructor-&gt;hasInstance(exec, jsValue); // false if an exception is thrown
</span><span class="cx">     if (exec-&gt;hadException()) {
</span><ins>+        JSValue exceptionValue = exec-&gt;exception();
</ins><span class="cx">         if (exception)
</span><del>-            *exception = toRef(exec, exec-&gt;exception());
</del><ins>+            *exception = toRef(exec, exceptionValue);
</ins><span class="cx">         exec-&gt;clearException();
</span><ins>+#if ENABLE(REMOTE_INSPECTOR)
+        exec-&gt;vmEntryGlobalObject()-&gt;inspectorController().reportAPIException(exec, exceptionValue);
+#endif
</ins><span class="cx">     }
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="lines">@@ -344,9 +356,13 @@
</span><span class="cx">     if (exception)
</span><span class="cx">         *exception = 0;
</span><span class="cx">     if (exec-&gt;hadException()) {
</span><ins>+        JSValue exceptionValue = exec-&gt;exception();
</ins><span class="cx">         if (exception)
</span><del>-            *exception = toRef(exec, exec-&gt;exception());
</del><ins>+            *exception = toRef(exec, exceptionValue);
</ins><span class="cx">         exec-&gt;clearException();
</span><ins>+#if ENABLE(REMOTE_INSPECTOR)
+        exec-&gt;vmEntryGlobalObject()-&gt;inspectorController().reportAPIException(exec, exceptionValue);
+#endif
</ins><span class="cx">         return 0;
</span><span class="cx">     }
</span><span class="cx">     return OpaqueJSString::create(result).leakRef();
</span><span class="lines">@@ -378,9 +394,13 @@
</span><span class="cx"> 
</span><span class="cx">     double number = jsValue.toNumber(exec);
</span><span class="cx">     if (exec-&gt;hadException()) {
</span><ins>+        JSValue exceptionValue = exec-&gt;exception();
</ins><span class="cx">         if (exception)
</span><del>-            *exception = toRef(exec, exec-&gt;exception());
</del><ins>+            *exception = toRef(exec, exceptionValue);
</ins><span class="cx">         exec-&gt;clearException();
</span><ins>+#if ENABLE(REMOTE_INSPECTOR)
+        exec-&gt;vmEntryGlobalObject()-&gt;inspectorController().reportAPIException(exec, exceptionValue);
+#endif
</ins><span class="cx">         number = QNaN;
</span><span class="cx">     }
</span><span class="cx">     return number;
</span><span class="lines">@@ -399,9 +419,13 @@
</span><span class="cx">     
</span><span class="cx">     RefPtr&lt;OpaqueJSString&gt; stringRef(OpaqueJSString::create(jsValue.toString(exec)-&gt;value(exec)));
</span><span class="cx">     if (exec-&gt;hadException()) {
</span><ins>+        JSValue exceptionValue = exec-&gt;exception();
</ins><span class="cx">         if (exception)
</span><del>-            *exception = toRef(exec, exec-&gt;exception());
</del><ins>+            *exception = toRef(exec, exceptionValue);
</ins><span class="cx">         exec-&gt;clearException();
</span><ins>+#if ENABLE(REMOTE_INSPECTOR)
+        exec-&gt;vmEntryGlobalObject()-&gt;inspectorController().reportAPIException(exec, exceptionValue);
+#endif
</ins><span class="cx">         stringRef.clear();
</span><span class="cx">     }
</span><span class="cx">     return stringRef.release().leakRef();
</span><span class="lines">@@ -420,13 +444,17 @@
</span><span class="cx">     
</span><span class="cx">     JSObjectRef objectRef = toRef(jsValue.toObject(exec));
</span><span class="cx">     if (exec-&gt;hadException()) {
</span><ins>+        JSValue exceptionValue = exec-&gt;exception();
</ins><span class="cx">         if (exception)
</span><del>-            *exception = toRef(exec, exec-&gt;exception());
</del><ins>+            *exception = toRef(exec, exceptionValue);
</ins><span class="cx">         exec-&gt;clearException();
</span><ins>+#if ENABLE(REMOTE_INSPECTOR)
+        exec-&gt;vmEntryGlobalObject()-&gt;inspectorController().reportAPIException(exec, exceptionValue);
+#endif
</ins><span class="cx">         objectRef = 0;
</span><span class="cx">     }
</span><span class="cx">     return objectRef;
</span><del>-}    
</del><ins>+}
</ins><span class="cx"> 
</span><span class="cx"> void JSValueProtect(JSContextRef ctx, JSValueRef value)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (164823 => 164824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-02-27 20:37:51 UTC (rev 164823)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-02-27 20:45:08 UTC (rev 164824)
</span><span class="lines">@@ -1,3 +1,87 @@
</span><ins>+2014-02-27  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
+
+        Web Inspector: JSContext inspection should report exceptions in the console
+        https://bugs.webkit.org/show_bug.cgi?id=128776
+
+        Reviewed by Timothy Hatcher.
+
+        When JavaScript API functions have an exception, let the inspector
+        know so it can log the JavaScript and Native backtrace that caused
+        the exception.
+
+        Include some clean up of ConsoleMessage and ScriptCallStack construction.
+
+        * API/JSBase.cpp:
+        (JSEvaluateScript):
+        (JSCheckScriptSyntax):
+        * API/JSObjectRef.cpp:
+        (JSObjectMakeFunction):
+        (JSObjectMakeArray):
+        (JSObjectMakeDate):
+        (JSObjectMakeError):
+        (JSObjectMakeRegExp):
+        (JSObjectGetProperty):
+        (JSObjectSetProperty):
+        (JSObjectGetPropertyAtIndex):
+        (JSObjectSetPropertyAtIndex):
+        (JSObjectDeleteProperty):
+        (JSObjectCallAsFunction):
+        (JSObjectCallAsConstructor):
+        * API/JSValue.mm:
+        (reportExceptionToInspector):
+        (valueToArray):
+        (valueToDictionary):
+        * API/JSValueRef.cpp:
+        (JSValueIsEqual):
+        (JSValueIsInstanceOfConstructor):
+        (JSValueCreateJSONString):
+        (JSValueToNumber):
+        (JSValueToStringCopy):
+        (JSValueToObject):
+        When seeing an exception, let the inspector know there was an exception.
+
+        * inspector/JSGlobalObjectInspectorController.h:
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
+        (Inspector::JSGlobalObjectInspectorController::appendAPIBacktrace):
+        (Inspector::JSGlobalObjectInspectorController::reportAPIException):
+        Log API exceptions by also grabbing the native backtrace.
+
+        * inspector/ScriptCallStack.h:
+        * inspector/ScriptCallStack.cpp:
+        (Inspector::ScriptCallStack::firstNonNativeCallFrame):
+        (Inspector::ScriptCallStack::append):
+        Minor extensions to ScriptCallStack to make it easier to work with.
+
+        * inspector/ConsoleMessage.cpp:
+        (Inspector::ConsoleMessage::ConsoleMessage):
+        (Inspector::ConsoleMessage::autogenerateMetadata):
+        Provide better default information if the first call frame was native.
+
+        * inspector/ScriptCallStackFactory.cpp:
+        (Inspector::createScriptCallStack):
+        (Inspector::extractSourceInformationFromException):
+        (Inspector::createScriptCallStackFromException):
+        Perform the handling here of inserting a fake call frame for exceptions
+        if there was no call stack (e.g. a SyntaxError) or if the first call
+        frame had no information.
+
+        * inspector/ConsoleMessage.cpp:
+        (Inspector::ConsoleMessage::ConsoleMessage):
+        (Inspector::ConsoleMessage::autogenerateMetadata):
+        * inspector/ConsoleMessage.h:
+        * inspector/ScriptCallStackFactory.cpp:
+        (Inspector::createScriptCallStack):
+        (Inspector::createScriptCallStackForConsole):
+        * inspector/ScriptCallStackFactory.h:
+        * inspector/agents/InspectorConsoleAgent.cpp:
+        (Inspector::InspectorConsoleAgent::enable):
+        (Inspector::InspectorConsoleAgent::addMessageToConsole):
+        (Inspector::InspectorConsoleAgent::count):
+        * inspector/agents/JSGlobalObjectDebuggerAgent.cpp:
+        (Inspector::JSGlobalObjectDebuggerAgent::breakpointActionLog):
+        ConsoleMessage cleanup.
+
</ins><span class="cx"> 2014-02-27  David Kilzer  &lt;ddkilzer@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Create symlink to /usr/local/bin/jsc during installation
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorConsoleMessagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/ConsoleMessage.cpp (164823 => 164824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/ConsoleMessage.cpp        2014-02-27 20:37:51 UTC (rev 164823)
+++ trunk/Source/JavaScriptCore/inspector/ConsoleMessage.cpp        2014-02-27 20:45:08 UTC (rev 164824)
</span><span class="lines">@@ -45,7 +45,7 @@
</span><span class="cx"> 
</span><span class="cx"> namespace Inspector {
</span><span class="cx"> 
</span><del>-ConsoleMessage::ConsoleMessage(bool canGenerateCallStack, MessageSource source, MessageType type, MessageLevel level, const String&amp; message, unsigned long requestIdentifier)
</del><ins>+ConsoleMessage::ConsoleMessage(MessageSource source, MessageType type, MessageLevel level, const String&amp; message, unsigned long requestIdentifier)
</ins><span class="cx">     : m_source(source)
</span><span class="cx">     , m_type(type)
</span><span class="cx">     , m_level(level)
</span><span class="lines">@@ -56,10 +56,9 @@
</span><span class="cx">     , m_repeatCount(1)
</span><span class="cx">     , m_requestId(IdentifiersFactory::requestId(requestIdentifier))
</span><span class="cx"> {
</span><del>-    autogenerateMetadata(canGenerateCallStack);
</del><span class="cx"> }
</span><span class="cx"> 
</span><del>-ConsoleMessage::ConsoleMessage(bool canGenerateCallStack, MessageSource source, MessageType type, MessageLevel level, const String&amp; message, const String&amp; url, unsigned line, unsigned column, JSC::ExecState* state, unsigned long requestIdentifier)
</del><ins>+ConsoleMessage::ConsoleMessage(MessageSource source, MessageType type, MessageLevel level, const String&amp; message, const String&amp; url, unsigned line, unsigned column, JSC::ExecState* state, unsigned long requestIdentifier)
</ins><span class="cx">     : m_source(source)
</span><span class="cx">     , m_type(type)
</span><span class="cx">     , m_level(level)
</span><span class="lines">@@ -70,30 +69,31 @@
</span><span class="cx">     , m_repeatCount(1)
</span><span class="cx">     , m_requestId(IdentifiersFactory::requestId(requestIdentifier))
</span><span class="cx"> {
</span><del>-    autogenerateMetadata(canGenerateCallStack, state);
</del><ins>+    autogenerateMetadata(state);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-ConsoleMessage::ConsoleMessage(bool, MessageSource source, MessageType type, MessageLevel level, const String&amp; message, PassRefPtr&lt;ScriptCallStack&gt; callStack, unsigned long requestIdentifier)
</del><ins>+ConsoleMessage::ConsoleMessage(MessageSource source, MessageType type, MessageLevel level, const String&amp; message, PassRefPtr&lt;ScriptCallStack&gt; callStack, unsigned long requestIdentifier)
</ins><span class="cx">     : m_source(source)
</span><span class="cx">     , m_type(type)
</span><span class="cx">     , m_level(level)
</span><span class="cx">     , m_message(message)
</span><del>-    , m_arguments(nullptr)
</del><ins>+    , m_url()
</ins><span class="cx">     , m_line(0)
</span><span class="cx">     , m_column(0)
</span><span class="cx">     , m_repeatCount(1)
</span><span class="cx">     , m_requestId(IdentifiersFactory::requestId(requestIdentifier))
</span><span class="cx"> {
</span><del>-    if (callStack &amp;&amp; callStack-&gt;size()) {
-        const ScriptCallFrame&amp; frame = callStack-&gt;at(0);
-        m_url = frame.sourceURL();
-        m_line = frame.lineNumber();
-        m_column = frame.columnNumber();
-    }
</del><span class="cx">     m_callStack = callStack;
</span><ins>+
+    const ScriptCallFrame* frame = m_callStack ? m_callStack-&gt;firstNonNativeCallFrame() : nullptr;
+    if (frame) {
+        m_url = frame-&gt;sourceURL();
+        m_line = frame-&gt;lineNumber();
+        m_column = frame-&gt;columnNumber();
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-ConsoleMessage::ConsoleMessage(bool canGenerateCallStack, MessageSource source, MessageType type, MessageLevel level, const String&amp; message, PassRefPtr&lt;ScriptArguments&gt; arguments, JSC::ExecState* state, unsigned long requestIdentifier)
</del><ins>+ConsoleMessage::ConsoleMessage(MessageSource source, MessageType type, MessageLevel level, const String&amp; message, PassRefPtr&lt;ScriptArguments&gt; arguments, JSC::ExecState* state, unsigned long requestIdentifier)
</ins><span class="cx">     : m_source(source)
</span><span class="cx">     , m_type(type)
</span><span class="cx">     , m_level(level)
</span><span class="lines">@@ -105,35 +105,30 @@
</span><span class="cx">     , m_repeatCount(1)
</span><span class="cx">     , m_requestId(IdentifiersFactory::requestId(requestIdentifier))
</span><span class="cx"> {
</span><del>-    autogenerateMetadata(canGenerateCallStack, state);
</del><ins>+    autogenerateMetadata(state);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> ConsoleMessage::~ConsoleMessage()
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// FIXME: Remove the generate without ExecState path. The caller should always provide an ExecState.
-void ConsoleMessage::autogenerateMetadata(bool /*canGenerateCallStack*/, JSC::ExecState* state)
</del><ins>+void ConsoleMessage::autogenerateMetadata(JSC::ExecState* state)
</ins><span class="cx"> {
</span><del>-    if (m_type == MessageType::EndGroup)
</del><ins>+    if (!state)
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    if (state)
-        m_callStack = createScriptCallStackForConsole(state);
-    // else if (canGenerateCallStack)
-    //     m_callStack = createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture, true);
-    else
</del><ins>+    if (m_type == MessageType::EndGroup)
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    if (m_callStack &amp;&amp; m_callStack-&gt;size()) {
-        const ScriptCallFrame&amp; frame = m_callStack-&gt;at(0);
-        m_url = frame.sourceURL();
-        m_line = frame.lineNumber();
-        m_column = frame.columnNumber();
</del><ins>+    // FIXME: Should this really be using &quot;for console&quot; in the generic ConsoleMessage autogeneration? This can skip the first frame.
+    m_callStack = createScriptCallStackForConsole(state, ScriptCallStack::maxCallStackSizeToCapture);
+
+    if (const ScriptCallFrame* frame = m_callStack-&gt;firstNonNativeCallFrame()) {
+        m_url = frame-&gt;sourceURL();
+        m_line = frame-&gt;lineNumber();
+        m_column = frame-&gt;columnNumber();
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><del>-
-    m_callStack.clear();
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static Inspector::TypeBuilder::Console::ConsoleMessage::Source::Enum messageSourceValue(MessageSource source)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorConsoleMessageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/ConsoleMessage.h (164823 => 164824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/ConsoleMessage.h        2014-02-27 20:37:51 UTC (rev 164823)
+++ trunk/Source/JavaScriptCore/inspector/ConsoleMessage.h        2014-02-27 20:45:08 UTC (rev 164824)
</span><span class="lines">@@ -51,10 +51,10 @@
</span><span class="cx">     WTF_MAKE_NONCOPYABLE(ConsoleMessage);
</span><span class="cx">     WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><del>-    ConsoleMessage(bool canGenerateCallStack, MessageSource, MessageType, MessageLevel, const String&amp; message, unsigned long requestIdentifier = 0);
-    ConsoleMessage(bool canGenerateCallStack, MessageSource, MessageType, MessageLevel, const String&amp; message, const String&amp; url, unsigned line, unsigned column, JSC::ExecState* = nullptr, unsigned long requestIdentifier = 0);
-    ConsoleMessage(bool canGenerateCallStack, MessageSource, MessageType, MessageLevel, const String&amp; message, PassRefPtr&lt;ScriptCallStack&gt;, unsigned long requestIdentifier = 0);
-    ConsoleMessage(bool canGenerateCallStack, MessageSource, MessageType, MessageLevel, const String&amp; message, PassRefPtr&lt;ScriptArguments&gt;, JSC::ExecState*, unsigned long requestIdentifier = 0);
</del><ins>+    ConsoleMessage(MessageSource, MessageType, MessageLevel, const String&amp; message, unsigned long requestIdentifier = 0);
+    ConsoleMessage(MessageSource, MessageType, MessageLevel, const String&amp; message, const String&amp; url, unsigned line, unsigned column, JSC::ExecState* = nullptr, unsigned long requestIdentifier = 0);
+    ConsoleMessage(MessageSource, MessageType, MessageLevel, const String&amp; message, PassRefPtr&lt;ScriptCallStack&gt;, unsigned long requestIdentifier = 0);
+    ConsoleMessage(MessageSource, MessageType, MessageLevel, const String&amp; message, PassRefPtr&lt;ScriptArguments&gt;, JSC::ExecState*, unsigned long requestIdentifier = 0);
</ins><span class="cx">     ~ConsoleMessage();
</span><span class="cx"> 
</span><span class="cx">     void addToFrontend(InspectorConsoleFrontendDispatcher*, InjectedScriptManager*, bool generatePreview);
</span><span class="lines">@@ -74,7 +74,7 @@
</span><span class="cx">     void clear();
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    void autogenerateMetadata(bool canGenerateCallStack, JSC::ExecState* = nullptr);
</del><ins>+    void autogenerateMetadata(JSC::ExecState* = nullptr);
</ins><span class="cx"> 
</span><span class="cx">     MessageSource m_source;
</span><span class="cx">     MessageType m_type;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorJSGlobalObjectInspectorControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp (164823 => 164824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp        2014-02-27 20:37:51 UTC (rev 164823)
+++ trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp        2014-02-27 20:45:08 UTC (rev 164824)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> #if ENABLE(INSPECTOR)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;Completion.h&quot;
</span><ins>+#include &quot;ErrorHandlingScope.h&quot;
</ins><span class="cx"> #include &quot;InjectedScriptHost.h&quot;
</span><span class="cx"> #include &quot;InjectedScriptManager.h&quot;
</span><span class="cx"> #include &quot;InspectorAgent.h&quot;
</span><span class="lines">@@ -38,6 +39,11 @@
</span><span class="cx"> #include &quot;JSGlobalObjectConsoleAgent.h&quot;
</span><span class="cx"> #include &quot;JSGlobalObjectDebuggerAgent.h&quot;
</span><span class="cx"> #include &quot;JSGlobalObjectRuntimeAgent.h&quot;
</span><ins>+#include &quot;ScriptCallStack.h&quot;
+#include &quot;ScriptCallStackFactory.h&quot;
+#include &lt;cxxabi.h&gt;
+#include &lt;dlfcn.h&gt;
+#include &lt;execinfo.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> using namespace JSC;
</span><span class="cx"> 
</span><span class="lines">@@ -52,6 +58,8 @@
</span><span class="cx">     auto consoleAgent = std::make_unique&lt;JSGlobalObjectConsoleAgent&gt;(m_injectedScriptManager.get());
</span><span class="cx">     auto debuggerAgent = std::make_unique&lt;JSGlobalObjectDebuggerAgent&gt;(m_injectedScriptManager.get(), m_globalObject, consoleAgent.get());
</span><span class="cx"> 
</span><ins>+    m_consoleAgent = consoleAgent.get();
+
</ins><span class="cx">     runtimeAgent-&gt;setScriptDebugServer(&amp;debuggerAgent-&gt;scriptDebugServer());
</span><span class="cx"> 
</span><span class="cx">     m_agents.append(std::make_unique&lt;InspectorAgent&gt;());
</span><span class="lines">@@ -101,6 +109,51 @@
</span><span class="cx">         m_inspectorBackendDispatcher-&gt;dispatch(message);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void JSGlobalObjectInspectorController::appendAPIBacktrace(ScriptCallStack* callStack)
+{
+    static const int framesToShow = 31;
+    static const int framesToSkip = 3; // WTFGetBacktrace, appendAPIBacktrace, reportAPIException.
+
+    void* samples[framesToShow + framesToSkip];
+    int frames = framesToShow + framesToSkip;
+    WTFGetBacktrace(samples, &amp;frames);
+
+    void** stack = samples + framesToSkip;
+    int size = frames - framesToSkip;
+    for (int i = 0; i &lt; size; ++i) {
+        const char* mangledName = nullptr;
+        char* cxaDemangled = nullptr;
+        Dl_info info;
+        if (dladdr(stack[i], &amp;info) &amp;&amp; info.dli_sname)
+            mangledName = info.dli_sname;
+        if (mangledName)
+            cxaDemangled = abi::__cxa_demangle(mangledName, nullptr, nullptr, nullptr);
+        if (mangledName || cxaDemangled)
+            callStack-&gt;append(ScriptCallFrame(cxaDemangled ? cxaDemangled : mangledName, ASCIILiteral(&quot;[native code]&quot;), 0, 0));
+        else
+            callStack-&gt;append(ScriptCallFrame(ASCIILiteral(&quot;?&quot;), ASCIILiteral(&quot;[native code]&quot;), 0, 0));
+        free(cxaDemangled);
+    }
+}
+
+void JSGlobalObjectInspectorController::reportAPIException(ExecState* exec, JSValue exception)
+{
+    if (isTerminatedExecutionException(exception))
+        return;
+
+    ErrorHandlingScope errorScope(exec-&gt;vm());
+
+    RefPtr&lt;ScriptCallStack&gt; callStack = createScriptCallStackFromException(exec, exception, ScriptCallStack::maxCallStackSizeToCapture);
+    appendAPIBacktrace(callStack.get());
+
+    // FIXME: &lt;http://webkit.org/b/115087&gt; Web Inspector: Should not evaluate JavaScript handling exceptions
+    // If this is a custom exception object, call toString on it to try and get a nice string representation for the exception.
+    String errorMessage = exception.toString(exec)-&gt;value(exec);
+    exec-&gt;clearException();
+
+    m_consoleAgent-&gt;addMessageToConsole(MessageSource::JS, MessageType::Log, MessageLevel::Error, errorMessage, callStack);
+}
+
</ins><span class="cx"> InspectorFunctionCallHandler JSGlobalObjectInspectorController::functionCallHandler() const
</span><span class="cx"> {
</span><span class="cx">     return JSC::call;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorJSGlobalObjectInspectorControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.h (164823 => 164824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.h        2014-02-27 20:37:51 UTC (rev 164823)
+++ trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.h        2014-02-27 20:45:08 UTC (rev 164824)
</span><span class="lines">@@ -37,13 +37,16 @@
</span><span class="cx"> namespace JSC {
</span><span class="cx"> class ExecState;
</span><span class="cx"> class JSGlobalObject;
</span><ins>+class JSValue;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> namespace Inspector {
</span><span class="cx"> 
</span><span class="cx"> class InjectedScriptManager;
</span><span class="cx"> class InspectorBackendDispatcher;
</span><ins>+class InspectorConsoleAgent;
</ins><span class="cx"> class InspectorFrontendChannel;
</span><ins>+class ScriptCallStack;
</ins><span class="cx"> 
</span><span class="cx"> class JSGlobalObjectInspectorController final : public InspectorEnvironment {
</span><span class="cx">     WTF_MAKE_NONCOPYABLE(JSGlobalObjectInspectorController);
</span><span class="lines">@@ -58,6 +61,8 @@
</span><span class="cx"> 
</span><span class="cx">     void globalObjectDestroyed();
</span><span class="cx"> 
</span><ins>+    void reportAPIException(JSC::ExecState*, JSC::JSValue exception);
+
</ins><span class="cx">     virtual bool developerExtrasEnabled() const override { return true; }
</span><span class="cx">     virtual bool canAccessInspectedScriptState(JSC::ExecState*) const override { return true; }
</span><span class="cx">     virtual InspectorFunctionCallHandler functionCallHandler() const override;
</span><span class="lines">@@ -66,8 +71,11 @@
</span><span class="cx">     virtual void didCallInjectedScriptFunction(JSC::ExecState*) override { }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    void appendAPIBacktrace(ScriptCallStack* callStack);
+
</ins><span class="cx">     JSC::JSGlobalObject&amp; m_globalObject;
</span><span class="cx">     std::unique_ptr&lt;InjectedScriptManager&gt; m_injectedScriptManager;
</span><ins>+    InspectorConsoleAgent* m_consoleAgent;
</ins><span class="cx">     InspectorAgentRegistry m_agents;
</span><span class="cx">     InspectorFrontendChannel* m_inspectorFrontendChannel;
</span><span class="cx">     RefPtr&lt;InspectorBackendDispatcher&gt; m_inspectorBackendDispatcher;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorScriptCallStackcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/ScriptCallStack.cpp (164823 => 164824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/ScriptCallStack.cpp        2014-02-27 20:37:51 UTC (rev 164823)
+++ trunk/Source/JavaScriptCore/inspector/ScriptCallStack.cpp        2014-02-27 20:45:08 UTC (rev 164824)
</span><span class="lines">@@ -36,11 +36,20 @@
</span><span class="cx"> 
</span><span class="cx"> namespace Inspector {
</span><span class="cx"> 
</span><ins>+PassRefPtr&lt;ScriptCallStack&gt; ScriptCallStack::create()
+{
+    return adoptRef(new ScriptCallStack);
+}
+
</ins><span class="cx"> PassRefPtr&lt;ScriptCallStack&gt; ScriptCallStack::create(Vector&lt;ScriptCallFrame&gt;&amp; frames)
</span><span class="cx"> {
</span><span class="cx">     return adoptRef(new ScriptCallStack(frames));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+ScriptCallStack::ScriptCallStack()
+{
+}
+
</ins><span class="cx"> ScriptCallStack::ScriptCallStack(Vector&lt;ScriptCallFrame&gt;&amp; frames)
</span><span class="cx"> {
</span><span class="cx">     m_frames.swap(frames);
</span><span class="lines">@@ -61,6 +70,25 @@
</span><span class="cx">     return m_frames.size();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+const ScriptCallFrame* ScriptCallStack::firstNonNativeCallFrame() const
+{
+    if (!m_frames.size())
+        return nullptr;
+
+    for (size_t i = 0; i &lt; m_frames.size(); ++i) {
+        const ScriptCallFrame&amp; frame = m_frames[i];
+        if (frame.sourceURL() != &quot;[native code]&quot;)
+            return &amp;frame;
+    }
+
+    return nullptr;
+}
+
+void ScriptCallStack::append(const ScriptCallFrame&amp; frame)
+{
+    m_frames.append(frame);
+}
+
</ins><span class="cx"> bool ScriptCallStack::isEqual(ScriptCallStack* o) const
</span><span class="cx"> {
</span><span class="cx">     if (!o)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorScriptCallStackh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/ScriptCallStack.h (164823 => 164824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/ScriptCallStack.h        2014-02-27 20:37:51 UTC (rev 164823)
+++ trunk/Source/JavaScriptCore/inspector/ScriptCallStack.h        2014-02-27 20:45:08 UTC (rev 164824)
</span><span class="lines">@@ -47,6 +47,7 @@
</span><span class="cx"> public:
</span><span class="cx">     static const size_t maxCallStackSizeToCapture = 200;
</span><span class="cx">     
</span><ins>+    static PassRefPtr&lt;ScriptCallStack&gt; create();
</ins><span class="cx">     static PassRefPtr&lt;ScriptCallStack&gt; create(Vector&lt;ScriptCallFrame&gt;&amp;);
</span><span class="cx"> 
</span><span class="cx">     ~ScriptCallStack();
</span><span class="lines">@@ -54,6 +55,10 @@
</span><span class="cx">     const ScriptCallFrame&amp; at(size_t) const;
</span><span class="cx">     size_t size() const;
</span><span class="cx"> 
</span><ins>+    const ScriptCallFrame* firstNonNativeCallFrame() const;
+
+    void append(const ScriptCallFrame&amp;);
+
</ins><span class="cx">     bool isEqual(ScriptCallStack*) const;
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(INSPECTOR)
</span><span class="lines">@@ -61,6 +66,7 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    ScriptCallStack();
</ins><span class="cx">     ScriptCallStack(Vector&lt;ScriptCallFrame&gt;&amp;);
</span><span class="cx"> 
</span><span class="cx">     Vector&lt;ScriptCallFrame&gt; m_frames;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorScriptCallStackFactorycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/ScriptCallStackFactory.cpp (164823 => 164824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/ScriptCallStackFactory.cpp        2014-02-27 20:37:51 UTC (rev 164823)
+++ trunk/Source/JavaScriptCore/inspector/ScriptCallStackFactory.cpp        2014-02-27 20:45:08 UTC (rev 164824)
</span><span class="lines">@@ -83,28 +83,25 @@
</span><span class="cx">     size_t m_remainingCapacityForFrameCapture;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-PassRefPtr&lt;ScriptCallStack&gt; createScriptCallStack(JSC::ExecState* exec, size_t maxStackSize, bool emptyIsAllowed)
</del><ins>+PassRefPtr&lt;ScriptCallStack&gt; createScriptCallStack(JSC::ExecState* exec, size_t maxStackSize)
</ins><span class="cx"> {
</span><ins>+    if (!exec)
+        return ScriptCallStack::create();
+
</ins><span class="cx">     Vector&lt;ScriptCallFrame&gt; frames;
</span><span class="cx"> 
</span><del>-    if (exec) {
-        CallFrame* frame = exec-&gt;vm().topCallFrame;
-        CreateScriptCallStackFunctor functor(false, frames, maxStackSize);
-        frame-&gt;iterate(functor);
-    }
</del><ins>+    CallFrame* frame = exec-&gt;vm().topCallFrame;
+    CreateScriptCallStackFunctor functor(false, frames, maxStackSize);
+    frame-&gt;iterate(functor);
</ins><span class="cx"> 
</span><del>-    if (frames.isEmpty() &amp;&amp; !emptyIsAllowed) {
-        // No frames found. It may happen in the case where
-        // a bound function is called from native code for example.
-        // Fallback to setting lineNumber to 0, and source and function name to &quot;undefined&quot;.
-        frames.append(ScriptCallFrame(ASCIILiteral(&quot;undefined&quot;), ASCIILiteral(&quot;undefined&quot;), 0, 0));
-    }
-
</del><span class="cx">     return ScriptCallStack::create(frames);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-PassRefPtr&lt;ScriptCallStack&gt; createScriptCallStack(JSC::ExecState* exec, size_t maxStackSize)
</del><ins>+PassRefPtr&lt;ScriptCallStack&gt; createScriptCallStackForConsole(JSC::ExecState* exec, size_t maxStackSize)
</ins><span class="cx"> {
</span><ins>+    if (!exec)
+        return ScriptCallStack::create();
+
</ins><span class="cx">     Vector&lt;ScriptCallFrame&gt; frames;
</span><span class="cx"> 
</span><span class="cx">     CallFrame* frame = exec-&gt;vm().topCallFrame;
</span><span class="lines">@@ -119,10 +116,16 @@
</span><span class="cx">     return ScriptCallStack::create(frames);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-PassRefPtr&lt;ScriptCallStack&gt; createScriptCallStackForConsole(JSC::ExecState* exec)
</del><ins>+static void extractSourceInformationFromException(JSC::ExecState* exec, JSObject* exceptionObject, int* lineNumber, int* columnNumber, String* sourceURL)
</ins><span class="cx"> {
</span><del>-    // FIXME: Caller should use createScriptCallStack alternative with the exec and appropriate max.
-    return createScriptCallStack(exec, ScriptCallStack::maxCallStackSizeToCapture);
</del><ins>+    // FIXME: &lt;http://webkit.org/b/115087&gt; Web Inspector: Should not need to evaluate JavaScript handling exceptions
+    JSValue lineValue = exceptionObject-&gt;getDirect(exec-&gt;vm(), Identifier(exec, &quot;line&quot;));
+    *lineNumber = lineValue &amp;&amp; lineValue.isNumber() ? int(lineValue.toNumber(exec)) : 0;
+    JSValue columnValue = exceptionObject-&gt;getDirect(exec-&gt;vm(), Identifier(exec, &quot;column&quot;));
+    *columnNumber = columnValue &amp;&amp; columnValue.isNumber() ? int(columnValue.toNumber(exec)) : 0;
+    JSValue sourceURLValue = exceptionObject-&gt;getDirect(exec-&gt;vm(), Identifier(exec, &quot;sourceURL&quot;));
+    *sourceURL = sourceURLValue &amp;&amp; sourceURLValue.isString() ? sourceURLValue.toString(exec)-&gt;value(exec) : String(&quot;undefined&quot;);
+    exec-&gt;clearException();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> PassRefPtr&lt;ScriptCallStack&gt; createScriptCallStackFromException(JSC::ExecState* exec, JSC::JSValue&amp; exception, size_t maxStackSize)
</span><span class="lines">@@ -130,29 +133,28 @@
</span><span class="cx">     Vector&lt;ScriptCallFrame&gt; frames;
</span><span class="cx">     RefCountedArray&lt;StackFrame&gt; stackTrace = exec-&gt;vm().exceptionStack();
</span><span class="cx">     for (size_t i = 0; i &lt; stackTrace.size() &amp;&amp; i &lt; maxStackSize; i++) {
</span><del>-        if (!stackTrace[i].callee &amp;&amp; frames.size())
-            break;
-
</del><span class="cx">         unsigned line;
</span><span class="cx">         unsigned column;
</span><span class="cx">         stackTrace[i].computeLineAndColumn(line, column);
</span><span class="cx">         String functionName = stackTrace[i].friendlyFunctionName(exec);
</span><del>-        frames.append(ScriptCallFrame(functionName, stackTrace[i].sourceURL, line, column));
</del><ins>+        frames.append(ScriptCallFrame(functionName, stackTrace[i].friendlySourceURL(), line, column));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // FIXME: &lt;http://webkit.org/b/115087&gt; Web Inspector: WebCore::reportException should not evaluate JavaScript handling exceptions
-    // Fallback to getting at least the line and sourceURL from the exception if it has values and the exceptionStack doesn't.
-    if (frames.size() &gt; 0) {
-        const ScriptCallFrame&amp; firstCallFrame = frames.first();
-        JSObject* exceptionObject = exception.toObject(exec);
-        if (exception.isObject() &amp;&amp; firstCallFrame.sourceURL().isEmpty()) {
-            JSValue lineValue = exceptionObject-&gt;getDirect(exec-&gt;vm(), Identifier(exec, &quot;line&quot;));
-            int lineNumber = lineValue &amp;&amp; lineValue.isNumber() ? int(lineValue.toNumber(exec)) : 0;
-            JSValue columnValue = exceptionObject-&gt;getDirect(exec-&gt;vm(), Identifier(exec, &quot;column&quot;));
-            int columnNumber = columnValue &amp;&amp; columnValue.isNumber() ? int(columnValue.toNumber(exec)) : 0;
-            JSValue sourceURLValue = exceptionObject-&gt;getDirect(exec-&gt;vm(), Identifier(exec, &quot;sourceURL&quot;));
-            String exceptionSourceURL = sourceURLValue &amp;&amp; sourceURLValue.isString() ? sourceURLValue.toString(exec)-&gt;value(exec) : ASCIILiteral(&quot;undefined&quot;);
-            frames[0] = ScriptCallFrame(firstCallFrame.functionName(), exceptionSourceURL, lineNumber, columnNumber);
</del><ins>+    // Fallback to getting at least the line and sourceURL from the exception object if it has values and the exceptionStack doesn't.
+    JSObject* exceptionObject = exception.toObject(exec);
+    if (exception.isObject()) {
+        int lineNumber;
+        int columnNumber;
+        String exceptionSourceURL;
+        if (!frames.size()) {
+            extractSourceInformationFromException(exec, exceptionObject, &amp;lineNumber, &amp;columnNumber, &amp;exceptionSourceURL);
+            frames.append(ScriptCallFrame(String(), exceptionSourceURL, lineNumber, columnNumber));
+        } else {
+            if (stackTrace[0].sourceURL.isEmpty()) {
+                const ScriptCallFrame&amp; firstCallFrame = frames.first();
+                extractSourceInformationFromException(exec, exceptionObject, &amp;lineNumber, &amp;columnNumber, &amp;exceptionSourceURL);
+                frames[0] = ScriptCallFrame(firstCallFrame.functionName(), exceptionSourceURL, lineNumber, columnNumber);
+            }
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorScriptCallStackFactoryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/ScriptCallStackFactory.h (164823 => 164824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/ScriptCallStackFactory.h        2014-02-27 20:37:51 UTC (rev 164823)
+++ trunk/Source/JavaScriptCore/inspector/ScriptCallStackFactory.h        2014-02-27 20:45:08 UTC (rev 164824)
</span><span class="lines">@@ -45,9 +45,8 @@
</span><span class="cx"> class ScriptCallStack;
</span><span class="cx"> 
</span><span class="cx"> // FIXME: The subtle differences between these should be eliminated.
</span><del>-JS_EXPORT_PRIVATE PassRefPtr&lt;ScriptCallStack&gt; createScriptCallStack(JSC::ExecState*, size_t maxStackSize, bool emptyIsAllowed);
</del><span class="cx"> JS_EXPORT_PRIVATE PassRefPtr&lt;ScriptCallStack&gt; createScriptCallStack(JSC::ExecState*, size_t maxStackSize);
</span><del>-JS_EXPORT_PRIVATE PassRefPtr&lt;ScriptCallStack&gt; createScriptCallStackForConsole(JSC::ExecState*);
</del><ins>+JS_EXPORT_PRIVATE PassRefPtr&lt;ScriptCallStack&gt; createScriptCallStackForConsole(JSC::ExecState*, size_t maxStackSize);
</ins><span class="cx"> JS_EXPORT_PRIVATE PassRefPtr&lt;ScriptCallStack&gt; createScriptCallStackFromException(JSC::ExecState*, JSC::JSValue&amp; exception, size_t maxStackSize);
</span><span class="cx"> JS_EXPORT_PRIVATE PassRefPtr&lt;ScriptArguments&gt; createScriptArguments(JSC::ExecState*, unsigned skipArgumentCount);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectoragentsInspectorConsoleAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/agents/InspectorConsoleAgent.cpp (164823 => 164824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/agents/InspectorConsoleAgent.cpp        2014-02-27 20:37:51 UTC (rev 164823)
+++ trunk/Source/JavaScriptCore/inspector/agents/InspectorConsoleAgent.cpp        2014-02-27 20:45:08 UTC (rev 164824)
</span><span class="lines">@@ -80,7 +80,7 @@
</span><span class="cx">     m_enabled = true;
</span><span class="cx"> 
</span><span class="cx">     if (m_expiredConsoleMessageCount) {
</span><del>-        ConsoleMessage expiredMessage(!isWorkerAgent(), MessageSource::Other, MessageType::Log, MessageLevel::Warning, String::format(&quot;%d console messages are not shown.&quot;, m_expiredConsoleMessageCount));
</del><ins>+        ConsoleMessage expiredMessage(MessageSource::Other, MessageType::Log, MessageLevel::Warning, String::format(&quot;%d console messages are not shown.&quot;, m_expiredConsoleMessageCount));
</ins><span class="cx">         expiredMessage.addToFrontend(m_frontendDispatcher.get(), m_injectedScriptManager, false);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -128,7 +128,7 @@
</span><span class="cx">         clearMessages(&amp;error);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    addConsoleMessage(std::make_unique&lt;ConsoleMessage&gt;(!isWorkerAgent(), source, type, level, message, callStack, requestIdentifier));
</del><ins>+    addConsoleMessage(std::make_unique&lt;ConsoleMessage&gt;(source, type, level, message, callStack, requestIdentifier));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void InspectorConsoleAgent::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, const String&amp; message, JSC::ExecState* state, PassRefPtr&lt;ScriptArguments&gt; arguments, unsigned long requestIdentifier)
</span><span class="lines">@@ -141,7 +141,7 @@
</span><span class="cx">         clearMessages(&amp;error);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    addConsoleMessage(std::make_unique&lt;ConsoleMessage&gt;(!isWorkerAgent(), source, type, level, message, arguments, state, requestIdentifier));
</del><ins>+    addConsoleMessage(std::make_unique&lt;ConsoleMessage&gt;(source, type, level, message, arguments, state, requestIdentifier));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void InspectorConsoleAgent::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, const String&amp; message, const String&amp; scriptID, unsigned lineNumber, unsigned columnNumber, JSC::ExecState* state, unsigned long requestIdentifier)
</span><span class="lines">@@ -154,8 +154,7 @@
</span><span class="cx">         clearMessages(&amp;error);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    bool canGenerateCallStack = !isWorkerAgent() &amp;&amp; m_frontendDispatcher;
-    addConsoleMessage(std::make_unique&lt;ConsoleMessage&gt;(canGenerateCallStack, source, type, level, message, scriptID, lineNumber, columnNumber, state, requestIdentifier));
</del><ins>+    addConsoleMessage(std::make_unique&lt;ConsoleMessage&gt;(source, type, level, message, scriptID, lineNumber, columnNumber, state, requestIdentifier));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Vector&lt;unsigned&gt; InspectorConsoleAgent::consoleMessageArgumentCounts() const
</span><span class="lines">@@ -197,7 +196,7 @@
</span><span class="cx"> 
</span><span class="cx"> void InspectorConsoleAgent::count(JSC::ExecState* state, PassRefPtr&lt;ScriptArguments&gt; arguments)
</span><span class="cx"> {
</span><del>-    RefPtr&lt;ScriptCallStack&gt; callStack(createScriptCallStackForConsole(state));
</del><ins>+    RefPtr&lt;ScriptCallStack&gt; callStack(createScriptCallStackForConsole(state, ScriptCallStack::maxCallStackSizeToCapture));
</ins><span class="cx">     const ScriptCallFrame&amp; lastCaller = callStack-&gt;at(0);
</span><span class="cx">     // Follow Firebug's behavior of counting with null and undefined title in
</span><span class="cx">     // the same bucket as no argument
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectoragentsJSGlobalObjectDebuggerAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/agents/JSGlobalObjectDebuggerAgent.cpp (164823 => 164824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/agents/JSGlobalObjectDebuggerAgent.cpp        2014-02-27 20:37:51 UTC (rev 164823)
+++ trunk/Source/JavaScriptCore/inspector/agents/JSGlobalObjectDebuggerAgent.cpp        2014-02-27 20:45:08 UTC (rev 164824)
</span><span class="lines">@@ -69,7 +69,7 @@
</span><span class="cx"> 
</span><span class="cx"> void JSGlobalObjectDebuggerAgent::breakpointActionLog(JSC::ExecState* exec, const String&amp; message)
</span><span class="cx"> {
</span><del>-    m_consoleAgent-&gt;addMessageToConsole(MessageSource::JS, MessageType::Log, MessageLevel::Log, message, createScriptCallStack(exec, ScriptCallStack::maxCallStackSizeToCapture, true), 0);
</del><ins>+    m_consoleAgent-&gt;addMessageToConsole(MessageSource::JS, MessageType::Log, MessageLevel::Log, message, createScriptCallStack(exec, ScriptCallStack::maxCallStackSizeToCapture), 0);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace Inspector
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (164823 => 164824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-02-27 20:37:51 UTC (rev 164823)
+++ trunk/Source/WebCore/ChangeLog        2014-02-27 20:45:08 UTC (rev 164824)
</span><span class="lines">@@ -1,3 +1,40 @@
</span><ins>+2014-02-27  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
+
+        Web Inspector: JSContext inspection should report exceptions in the console
+        https://bugs.webkit.org/show_bug.cgi?id=128776
+
+        Reviewed by Timothy Hatcher.
+
+        Include some clean up of ConsoleMessage and ScriptCallStack construction.
+
+        Covered by existing tests.
+
+        * bindings/js/JSDOMBinding.cpp:
+        (WebCore::reportException):
+        Simplify code now that createStackTraceFromException handles it.
+
+        * page/ContentSecurityPolicy.cpp:
+        (WebCore::gatherSecurityPolicyViolationEventData):
+        (WebCore::ContentSecurityPolicy::reportViolation):
+        ScriptCallStack can give us the first non-native callframe.
+
+        * inspector/InspectorResourceAgent.cpp:
+        (WebCore::InspectorResourceAgent::buildInitiatorObject):
+        * inspector/PageDebuggerAgent.cpp:
+        (WebCore::PageDebuggerAgent::breakpointActionLog):
+        * inspector/TimelineRecordFactory.cpp:
+        (WebCore::TimelineRecordFactory::createGenericRecord):
+        * page/Console.cpp:
+        (WebCore::internalAddMessage):
+        (WebCore::Console::profile):
+        (WebCore::Console::profileEnd):
+        (WebCore::Console::timeEnd):
+        * page/ContentSecurityPolicy.cpp:
+        (WebCore::gatherSecurityPolicyViolationEventData):
+        (WebCore::ContentSecurityPolicy::reportViolation):
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::postMessage):
+
</ins><span class="cx"> 2014-02-27  Andreas Kling  &lt;akling@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Remove FeatureObserver.
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMBindingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp (164823 => 164824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp        2014-02-27 20:37:51 UTC (rev 164823)
+++ trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp        2014-02-27 20:45:08 UTC (rev 164824)
</span><span class="lines">@@ -172,20 +172,10 @@
</span><span class="cx">     int lineNumber = 0;
</span><span class="cx">     int columnNumber = 0;
</span><span class="cx">     String exceptionSourceURL;
</span><del>-    if (callStack-&gt;size()) {
-        const ScriptCallFrame&amp; frame = callStack-&gt;at(0);
-        lineNumber = frame.lineNumber();
-        columnNumber = frame.columnNumber();
-        exceptionSourceURL = frame.sourceURL();
-    } else {
-        // There may not be an exceptionStack for a &lt;script&gt; SyntaxError. Fallback to getting at least the line and sourceURL from the exception.
-        JSObject* exceptionObject = exception.toObject(exec);
-        JSValue lineValue = exceptionObject-&gt;getDirect(exec-&gt;vm(), Identifier(exec, &quot;line&quot;));
-        lineNumber = lineValue &amp;&amp; lineValue.isNumber() ? int(lineValue.toNumber(exec)) : 0;
-        JSValue columnValue = exceptionObject-&gt;getDirect(exec-&gt;vm(), Identifier(exec, &quot;column&quot;));
-        columnNumber = columnValue &amp;&amp; columnValue.isNumber() ? int(columnValue.toNumber(exec)) : 0;
-        JSValue sourceURLValue = exceptionObject-&gt;getDirect(exec-&gt;vm(), Identifier(exec, &quot;sourceURL&quot;));
-        exceptionSourceURL = sourceURLValue &amp;&amp; sourceURLValue.isString() ? sourceURLValue.toString(exec)-&gt;value(exec) : ASCIILiteral(&quot;undefined&quot;);
</del><ins>+    if (const ScriptCallFrame* callFrame = callStack-&gt;firstNonNativeCallFrame()) {
+        lineNumber = callFrame-&gt;lineNumber();
+        columnNumber = callFrame-&gt;columnNumber();
+        exceptionSourceURL = callFrame-&gt;sourceURL();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     String errorMessage;
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorResourceAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorResourceAgent.cpp (164823 => 164824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorResourceAgent.cpp        2014-02-27 20:37:51 UTC (rev 164823)
+++ trunk/Source/WebCore/inspector/InspectorResourceAgent.cpp        2014-02-27 20:45:08 UTC (rev 164824)
</span><span class="lines">@@ -439,7 +439,7 @@
</span><span class="cx"> 
</span><span class="cx"> PassRefPtr&lt;Inspector::TypeBuilder::Network::Initiator&gt; InspectorResourceAgent::buildInitiatorObject(Document* document)
</span><span class="cx"> {
</span><del>-    RefPtr&lt;ScriptCallStack&gt; stackTrace = createScriptCallStack(JSMainThreadExecState::currentState(), ScriptCallStack::maxCallStackSizeToCapture, true);
</del><ins>+    RefPtr&lt;ScriptCallStack&gt; stackTrace = createScriptCallStack(JSMainThreadExecState::currentState(), ScriptCallStack::maxCallStackSizeToCapture);
</ins><span class="cx">     if (stackTrace &amp;&amp; stackTrace-&gt;size() &gt; 0) {
</span><span class="cx">         RefPtr&lt;Inspector::TypeBuilder::Network::Initiator&gt; initiatorObject = Inspector::TypeBuilder::Network::Initiator::create()
</span><span class="cx">             .setType(Inspector::TypeBuilder::Network::Initiator::Type::Script);
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorPageDebuggerAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/PageDebuggerAgent.cpp (164823 => 164824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/PageDebuggerAgent.cpp        2014-02-27 20:37:51 UTC (rev 164823)
+++ trunk/Source/WebCore/inspector/PageDebuggerAgent.cpp        2014-02-27 20:45:08 UTC (rev 164824)
</span><span class="lines">@@ -117,7 +117,7 @@
</span><span class="cx"> 
</span><span class="cx"> void PageDebuggerAgent::breakpointActionLog(JSC::ExecState* exec, const String&amp; message)
</span><span class="cx"> {
</span><del>-    m_pageAgent-&gt;page()-&gt;console().addMessage(MessageSource::JS, MessageLevel::Log, message, createScriptCallStack(exec, ScriptCallStack::maxCallStackSizeToCapture, true));
</del><ins>+    m_pageAgent-&gt;page()-&gt;console().addMessage(MessageSource::JS, MessageLevel::Log, message, createScriptCallStack(exec, ScriptCallStack::maxCallStackSizeToCapture));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> InjectedScript PageDebuggerAgent::injectedScriptForEval(ErrorString* errorString, const int* executionContextId)
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorTimelineRecordFactorycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/TimelineRecordFactory.cpp (164823 => 164824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/TimelineRecordFactory.cpp        2014-02-27 20:37:51 UTC (rev 164823)
+++ trunk/Source/WebCore/inspector/TimelineRecordFactory.cpp        2014-02-27 20:45:08 UTC (rev 164824)
</span><span class="lines">@@ -57,7 +57,7 @@
</span><span class="cx">     record-&gt;setNumber(&quot;startTime&quot;, startTime);
</span><span class="cx"> 
</span><span class="cx">     if (maxCallStackDepth) {
</span><del>-        RefPtr&lt;ScriptCallStack&gt; stackTrace = createScriptCallStack(JSMainThreadExecState::currentState(), maxCallStackDepth, true);
</del><ins>+        RefPtr&lt;ScriptCallStack&gt; stackTrace = createScriptCallStack(JSMainThreadExecState::currentState(), maxCallStackDepth);
</ins><span class="cx">         if (stackTrace &amp;&amp; stackTrace-&gt;size())
</span><span class="cx">             record-&gt;setValue(&quot;stackTrace&quot;, stackTrace-&gt;buildInspectorArray());
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebCorepageConsolecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/Console.cpp (164823 => 164824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/Console.cpp        2014-02-27 20:37:51 UTC (rev 164823)
+++ trunk/Source/WebCore/page/Console.cpp        2014-02-27 20:45:08 UTC (rev 164824)
</span><span class="lines">@@ -77,7 +77,7 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     size_t stackSize = printTrace ? ScriptCallStack::maxCallStackSizeToCapture : 1;
</span><del>-    RefPtr&lt;ScriptCallStack&gt; callStack(createScriptCallStack(state, stackSize));
</del><ins>+    RefPtr&lt;ScriptCallStack&gt; callStack(createScriptCallStackForConsole(state, stackSize));
</ins><span class="cx">     const ScriptCallFrame&amp; lastCaller = callStack-&gt;at(0);
</span><span class="cx"> 
</span><span class="cx">     String message;
</span><span class="lines">@@ -203,7 +203,7 @@
</span><span class="cx"> 
</span><span class="cx">     ScriptProfiler::start(state, resolvedTitle);
</span><span class="cx"> 
</span><del>-    RefPtr&lt;ScriptCallStack&gt; callStack(createScriptCallStack(state, 1));
</del><ins>+    RefPtr&lt;ScriptCallStack&gt; callStack(createScriptCallStackForConsole(state, 1));
</ins><span class="cx">     const ScriptCallFrame&amp; lastCaller = callStack-&gt;at(0);
</span><span class="cx">     InspectorInstrumentation::addStartProfilingMessageToConsole(page, resolvedTitle, lastCaller.lineNumber(), lastCaller.columnNumber(), lastCaller.sourceURL());
</span><span class="cx"> }
</span><span class="lines">@@ -222,7 +222,7 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     m_profiles.append(profile);
</span><del>-    RefPtr&lt;ScriptCallStack&gt; callStack(createScriptCallStack(state, 1));
</del><ins>+    RefPtr&lt;ScriptCallStack&gt; callStack(createScriptCallStackForConsole(state, 1));
</ins><span class="cx">     InspectorInstrumentation::addProfile(page, profile, callStack);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -233,7 +233,7 @@
</span><span class="cx"> 
</span><span class="cx"> void Console::timeEnd(JSC::ExecState* state, const String&amp; title)
</span><span class="cx"> {
</span><del>-    RefPtr&lt;ScriptCallStack&gt; callStack(createScriptCallStackForConsole(state));
</del><ins>+    RefPtr&lt;ScriptCallStack&gt; callStack(createScriptCallStackForConsole(state, 1));
</ins><span class="cx">     InspectorInstrumentation::stopConsoleTiming(m_frame, title, callStack.release());
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorepageContentSecurityPolicycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/ContentSecurityPolicy.cpp (164823 => 164824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/ContentSecurityPolicy.cpp        2014-02-27 20:37:51 UTC (rev 164823)
+++ trunk/Source/WebCore/page/ContentSecurityPolicy.cpp        2014-02-27 20:45:08 UTC (rev 164824)
</span><span class="lines">@@ -154,13 +154,20 @@
</span><span class="cx">     );
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-const ScriptCallFrame&amp; getFirstNonNativeFrame(PassRefPtr&lt;ScriptCallStack&gt; stack)
</del><ins>+FeatureObserver::Feature getFeatureObserverType(ContentSecurityPolicy::HeaderType type)
</ins><span class="cx"> {
</span><del>-    int frameNumber = 0;
-    if (!stack-&gt;at(0).lineNumber() &amp;&amp; stack-&gt;size() &gt; 1 &amp;&amp; stack-&gt;at(1).lineNumber())
-        frameNumber = 1;
-
-    return stack-&gt;at(frameNumber);
</del><ins>+    switch (type) {
+    case ContentSecurityPolicy::PrefixedEnforce:
+        return FeatureObserver::PrefixedContentSecurityPolicy;
+    case ContentSecurityPolicy::Enforce:
+        return FeatureObserver::ContentSecurityPolicy;
+    case ContentSecurityPolicy::PrefixedReport:
+        return FeatureObserver::PrefixedContentSecurityPolicyReportOnly;
+    case ContentSecurityPolicy::Report:
+        return FeatureObserver::ContentSecurityPolicyReportOnly;
+    }
+    ASSERT_NOT_REACHED();
+    return FeatureObserver::NumberOfFeatures;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace
</span><span class="lines">@@ -1704,16 +1711,12 @@
</span><span class="cx">     init.sourceFile = String();
</span><span class="cx">     init.lineNumber = 0;
</span><span class="cx"> 
</span><del>-    RefPtr&lt;ScriptCallStack&gt; stack = createScriptCallStack(JSMainThreadExecState::currentState(), 2, false);
-    if (!stack)
-        return;
-
-    const ScriptCallFrame&amp; callFrame = getFirstNonNativeFrame(stack);
-
-    if (callFrame.lineNumber()) {
-        URL source = URL(ParsedURLString, callFrame.sourceURL());
</del><ins>+    RefPtr&lt;ScriptCallStack&gt; stack = createScriptCallStack(JSMainThreadExecState::currentState(), 2);
+    const ScriptCallFrame* callFrame = stack-&gt;firstNonNativeCallFrame();
+    if (callFrame &amp;&amp; callFrame-&gt;lineNumber()) {
+        URL source = URL(URL(), callFrame-&gt;sourceURL());
</ins><span class="cx">         init.sourceFile = stripURLForUseInReport(document, source);
</span><del>-        init.lineNumber = callFrame.lineNumber();
</del><ins>+        init.lineNumber = callFrame-&gt;lineNumber();
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="lines">@@ -1754,31 +1757,28 @@
</span><span class="cx">     // harmless information.
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;InspectorObject&gt; cspReport = InspectorObject::create();
</span><del>-    cspReport-&gt;setString(&quot;document-uri&quot;, document-&gt;url().strippedForUseAsReferrer());
-    cspReport-&gt;setString(&quot;referrer&quot;, document-&gt;referrer());
-    cspReport-&gt;setString(&quot;violated-directive&quot;, directiveText);
</del><ins>+    cspReport-&gt;setString(ASCIILiteral(&quot;document-uri&quot;), document-&gt;url().strippedForUseAsReferrer());
+    cspReport-&gt;setString(ASCIILiteral(&quot;referrer&quot;), document-&gt;referrer());
+    cspReport-&gt;setString(ASCIILiteral(&quot;violated-directive&quot;), directiveText);
</ins><span class="cx"> #if ENABLE(CSP_NEXT)
</span><span class="cx">     if (experimentalFeaturesEnabled())
</span><del>-        cspReport-&gt;setString(&quot;effective-directive&quot;, effectiveDirective);
</del><ins>+        cspReport-&gt;setString(ASCIILiteral(&quot;effective-directive&quot;), effectiveDirective);
</ins><span class="cx"> #else
</span><span class="cx">     UNUSED_PARAM(effectiveDirective);
</span><span class="cx"> #endif
</span><del>-    cspReport-&gt;setString(&quot;original-policy&quot;, header);
-    cspReport-&gt;setString(&quot;blocked-uri&quot;, stripURLForUseInReport(document, blockedURL));
</del><ins>+    cspReport-&gt;setString(ASCIILiteral(&quot;original-policy&quot;), header);
+    cspReport-&gt;setString(ASCIILiteral(&quot;blocked-uri&quot;), stripURLForUseInReport(document, blockedURL));
</ins><span class="cx"> 
</span><del>-    RefPtr&lt;ScriptCallStack&gt; stack = createScriptCallStack(JSMainThreadExecState::currentState(), 2, false);
-    if (stack) {
-        const ScriptCallFrame&amp; callFrame = getFirstNonNativeFrame(stack);
-
-        if (callFrame.lineNumber()) {
-            URL source = URL(ParsedURLString, callFrame.sourceURL());
-            cspReport-&gt;setString(&quot;source-file&quot;, stripURLForUseInReport(document, source));
-            cspReport-&gt;setNumber(&quot;line-number&quot;, callFrame.lineNumber());
-        }
</del><ins>+    RefPtr&lt;ScriptCallStack&gt; stack = createScriptCallStack(JSMainThreadExecState::currentState(), 2);
+    const ScriptCallFrame* callFrame = stack-&gt;firstNonNativeCallFrame();
+    if (callFrame &amp;&amp; callFrame-&gt;lineNumber()) {
+        URL source = URL(URL(), callFrame-&gt;sourceURL());
+        cspReport-&gt;setString(ASCIILiteral(&quot;source-file&quot;), stripURLForUseInReport(document, source));
+        cspReport-&gt;setNumber(ASCIILiteral(&quot;line-number&quot;), callFrame-&gt;lineNumber());
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;InspectorObject&gt; reportObject = InspectorObject::create();
</span><del>-    reportObject-&gt;setObject(&quot;csp-report&quot;, cspReport.release());
</del><ins>+    reportObject-&gt;setObject(ASCIILiteral(&quot;csp-report&quot;), cspReport.release());
</ins><span class="cx"> 
</span><span class="cx">     RefPtr&lt;FormData&gt; report = FormData::create(reportObject-&gt;toJSONString().utf8());
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorepageDOMWindowcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/DOMWindow.cpp (164823 => 164824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/DOMWindow.cpp        2014-02-27 20:37:51 UTC (rev 164823)
+++ trunk/Source/WebCore/page/DOMWindow.cpp        2014-02-27 20:45:08 UTC (rev 164824)
</span><span class="lines">@@ -846,7 +846,7 @@
</span><span class="cx">     // Capture stack trace only when inspector front-end is loaded as it may be time consuming.
</span><span class="cx">     RefPtr&lt;ScriptCallStack&gt; stackTrace;
</span><span class="cx">     if (InspectorInstrumentation::consoleAgentEnabled(sourceDocument))
</span><del>-        stackTrace = createScriptCallStack(JSMainThreadExecState::currentState(), ScriptCallStack::maxCallStackSizeToCapture, true);
</del><ins>+        stackTrace = createScriptCallStack(JSMainThreadExecState::currentState(), ScriptCallStack::maxCallStackSizeToCapture);
</ins><span class="cx"> 
</span><span class="cx">     // Schedule the message.
</span><span class="cx">     PostMessageTimer* timer = new PostMessageTimer(this, message, sourceOrigin, &amp;source, std::move(channels), target.get(), stackTrace.release());
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (164823 => 164824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2014-02-27 20:37:51 UTC (rev 164823)
+++ trunk/Source/WebInspectorUI/ChangeLog        2014-02-27 20:45:08 UTC (rev 164824)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2014-02-27  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
+
+        Web Inspector: JSContext inspection should report exceptions in the console
+        https://bugs.webkit.org/show_bug.cgi?id=128776
+
+        Reviewed by Timothy Hatcher.
+
+        * UserInterface/ConsoleMessageImpl.js:
+        (WebInspector.ConsoleMessageImpl.prototype._formatMessage):
+        (WebInspector.ConsoleMessageImpl.prototype._shouldHideURL):
+        (WebInspector.ConsoleMessageImpl.prototype._firstNonNativeCallFrame):
+        (WebInspector.ConsoleMessageImpl.prototype._populateStackTraceTreeElement):
+        Provide better handling for &quot;[native code]&quot; and legacy &quot;undefined&quot;
+        call frame URLs. Never linkify these. Also, when showing a link
+        for an exception, always use the first non-native call frame as
+        the link location.
+
</ins><span class="cx"> 2014-02-26  Timothy Hatcher  &lt;timothy@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Fix an issue where the Timeline filter scope bars were not applying.
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsConsoleMessageImpljs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ConsoleMessageImpl.js (164823 => 164824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/ConsoleMessageImpl.js        2014-02-27 20:37:51 UTC (rev 164823)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ConsoleMessageImpl.js        2014-02-27 20:45:08 UTC (rev 164824)
</span><span class="lines">@@ -109,10 +109,11 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if (this.source !== WebInspector.ConsoleMessage.MessageSource.Network || this._request) {
</span><del>-            if (this._stackTrace &amp;&amp; this._stackTrace.length &amp;&amp; this._stackTrace[0].url) {
-                var urlElement = this._linkifyCallFrame(this._stackTrace[0]);
</del><ins>+            var firstNonNativeCallFrame = this._firstNonNativeCallFrame();
+            if (firstNonNativeCallFrame) {
+                var urlElement = this._linkifyCallFrame(firstNonNativeCallFrame);
</ins><span class="cx">                 this._formattedMessage.appendChild(urlElement);
</span><del>-            } else if (this.url &amp;&amp; this.url !== &quot;undefined&quot;) {
</del><ins>+            } else if (this.url &amp;&amp; !this._shouldHideURL(this.url)) {
</ins><span class="cx">                 var urlElement = this._linkifyLocation(this.url, this.line, this.column);
</span><span class="cx">                 this._formattedMessage.appendChild(urlElement);
</span><span class="cx">             }
</span><span class="lines">@@ -145,6 +146,26 @@
</span><span class="cx">         return !!this._stackTrace &amp;&amp; this._stackTrace.length &amp;&amp; (this.source === WebInspector.ConsoleMessage.MessageSource.Network || this.level === WebInspector.ConsoleMessage.MessageLevel.Error || this.type === WebInspector.ConsoleMessage.MessageType.Trace);
</span><span class="cx">     },
</span><span class="cx"> 
</span><ins>+    _shouldHideURL: function(url)
+    {
+        return url === &quot;undefined&quot; || url === &quot;[native code]&quot;;
+    },
+
+    _firstNonNativeCallFrame: function()
+    {
+        if (!this._stackTrace)
+            return null;
+
+        for (var i = 0; i &lt; this._stackTrace.length; i++) {
+            var frame = this._stackTrace[i];
+            if (!frame.url || frame.url === &quot;[native code]&quot;)
+                continue;
+            return frame;
+        }
+
+        return null;
+    },
+
</ins><span class="cx">     get message()
</span><span class="cx">     {
</span><span class="cx">         // force message formatting
</span><span class="lines">@@ -526,7 +547,7 @@
</span><span class="cx">             messageTextElement.appendChild(document.createTextNode(functionName));
</span><span class="cx">             content.appendChild(messageTextElement);
</span><span class="cx"> 
</span><del>-            if (frame.url) {
</del><ins>+            if (frame.url &amp;&amp; !this._shouldHideURL(frame.url)) {
</ins><span class="cx">                 var urlElement = this._linkifyCallFrame(frame);
</span><span class="cx">                 content.appendChild(urlElement);
</span><span class="cx">             }
</span></span></pre>
</div>
</div>

</body>
</html>