REGRESSION (r164507): Crash beneath JSGlobalObjectInspectorController::reportAPIExcep...
authormitz@apple.com <mitz@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 23 Feb 2014 05:44:05 +0000 (05:44 +0000)
committermitz@apple.com <mitz@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 23 Feb 2014 05:44:05 +0000 (05:44 +0000)
https://bugs.webkit.org/show_bug.cgi?id=129227

Reviewed by Eric Carlson.

Reverted r164507.

Source/JavaScriptCore:

* API/JSBase.cpp:
(JSEvaluateScript):
(JSCheckScriptSyntax):
* API/JSObjectRef.cpp:
(JSObjectMakeFunction):
(JSObjectMakeArray):
(JSObjectMakeDate):
(JSObjectMakeError):
(JSObjectMakeRegExp):
(JSObjectGetProperty):
(JSObjectSetProperty):
(JSObjectGetPropertyAtIndex):
(JSObjectSetPropertyAtIndex):
(JSObjectDeleteProperty):
(JSObjectCallAsFunction):
(JSObjectCallAsConstructor):
* API/JSValue.mm:
(valueToArray):
(valueToDictionary):
* API/JSValueRef.cpp:
(JSValueIsEqual):
(JSValueIsInstanceOfConstructor):
(JSValueCreateJSONString):
(JSValueToNumber):
(JSValueToStringCopy):
(JSValueToObject):
* inspector/ConsoleMessage.cpp:
(Inspector::ConsoleMessage::ConsoleMessage):
(Inspector::ConsoleMessage::autogenerateMetadata):
* inspector/ConsoleMessage.h:
* inspector/JSGlobalObjectInspectorController.cpp:
(Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
* inspector/JSGlobalObjectInspectorController.h:
* inspector/ScriptCallStack.cpp:
* inspector/ScriptCallStack.h:
* inspector/ScriptCallStackFactory.cpp:
(Inspector::createScriptCallStack):
(Inspector::createScriptCallStackForConsole):
(Inspector::createScriptCallStackFromException):
* inspector/ScriptCallStackFactory.h:
* inspector/agents/InspectorConsoleAgent.cpp:
(Inspector::InspectorConsoleAgent::enable):
(Inspector::InspectorConsoleAgent::addMessageToConsole):
(Inspector::InspectorConsoleAgent::count):
* inspector/agents/JSGlobalObjectDebuggerAgent.cpp:
(Inspector::JSGlobalObjectDebuggerAgent::breakpointActionLog):

Source/WebCore:

* bindings/js/JSDOMBinding.cpp:
(WebCore::reportException):
* 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/Views/ConsoleMessageImpl.js:
(WebInspector.ConsoleMessageImpl.prototype._formatMessage):
(WebInspector.ConsoleMessageImpl.prototype._populateStackTraceTreeElement):

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

25 files changed:
Source/JavaScriptCore/API/JSBase.cpp
Source/JavaScriptCore/API/JSObjectRef.cpp
Source/JavaScriptCore/API/JSValue.mm
Source/JavaScriptCore/API/JSValueRef.cpp
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/inspector/ConsoleMessage.cpp
Source/JavaScriptCore/inspector/ConsoleMessage.h
Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp
Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.h
Source/JavaScriptCore/inspector/ScriptCallStack.cpp
Source/JavaScriptCore/inspector/ScriptCallStack.h
Source/JavaScriptCore/inspector/ScriptCallStackFactory.cpp
Source/JavaScriptCore/inspector/ScriptCallStackFactory.h
Source/JavaScriptCore/inspector/agents/InspectorConsoleAgent.cpp
Source/JavaScriptCore/inspector/agents/JSGlobalObjectDebuggerAgent.cpp
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/JSDOMBinding.cpp
Source/WebCore/inspector/InspectorResourceAgent.cpp
Source/WebCore/inspector/PageDebuggerAgent.cpp
Source/WebCore/inspector/TimelineRecordFactory.cpp
Source/WebCore/page/Console.cpp
Source/WebCore/page/ContentSecurityPolicy.cpp
Source/WebCore/page/DOMWindow.cpp
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/UserInterface/Views/ConsoleMessageImpl.js

index d40784b..bc66835 100644 (file)
 #include "SourceCode.h"
 #include <wtf/text/StringHash.h>
 
-#if ENABLE(REMOTE_INSPECTOR)
-#include "JSGlobalObjectInspectorController.h"
-#endif
-
 using namespace JSC;
 
 JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef thisObject, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception)
@@ -69,14 +65,6 @@ JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef th
     if (evaluationException) {
         if (exception)
             *exception = toRef(exec, evaluationException);
-#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->inspectorController().reportAPIException(exec, evaluationException);
-#endif
         return 0;
     }
 
@@ -106,9 +94,6 @@ bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourc
     if (!isValidSyntax) {
         if (exception)
             *exception = toRef(exec, syntaxException);
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, syntaxException);
-#endif
         return false;
     }
 
index 870fd36..980eec3 100644 (file)
 #include "PropertyNameArray.h"
 #include "RegExpConstructor.h"
 
-#if ENABLE(REMOTE_INSPECTOR)
-#include "JSGlobalObjectInspectorController.h"
-#endif
-
 using namespace JSC;
 
 JSClassRef JSClassCreate(const JSClassDefinition* definition)
@@ -149,13 +145,9 @@ JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned pa
 
     JSObject* result = constructFunction(exec, exec->lexicalGlobalObject(), args, nameID, sourceURL->string(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()));
     if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
         if (exception)
-            *exception = toRef(exec, exceptionValue);
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
         result = 0;
     }
     return toRef(result);
@@ -181,13 +173,9 @@ JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSVa
         result = constructEmptyArray(exec, 0);
 
     if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
         if (exception)
-            *exception = toRef(exec, exceptionValue);
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
         result = 0;
     }
 
@@ -209,13 +197,9 @@ JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, const JSVal
 
     JSObject* result = constructDate(exec, exec->lexicalGlobalObject(), argList);
     if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
         if (exception)
-            *exception = toRef(exec, exceptionValue);
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
         result = 0;
     }
 
@@ -236,13 +220,9 @@ JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount, const JSVa
     JSObject* result = ErrorInstance::create(exec, errorStructure, message);
 
     if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
         if (exception)
-            *exception = toRef(exec, exceptionValue);
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
         result = 0;
     }
 
@@ -264,13 +244,9 @@ JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSV
 
     JSObject* result = constructRegExp(exec, exec->lexicalGlobalObject(),  argList);
     if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
         if (exception)
-            *exception = toRef(exec, exceptionValue);
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
         result = 0;
     }
     
@@ -332,13 +308,9 @@ JSValueRef JSObjectGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef
 
     JSValue jsValue = jsObject->get(exec, propertyName->identifier(&exec->vm()));
     if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
         if (exception)
-            *exception = toRef(exec, exceptionValue);
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
     }
     return toRef(exec, jsValue);
 }
@@ -365,13 +337,9 @@ void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef prope
     }
 
     if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
         if (exception)
-            *exception = toRef(exec, exceptionValue);
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
     }
 }
 
@@ -388,13 +356,9 @@ JSValueRef JSObjectGetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsi
 
     JSValue jsValue = jsObject->get(exec, propertyIndex);
     if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
         if (exception)
-            *exception = toRef(exec, exceptionValue);
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
     }
     return toRef(exec, jsValue);
 }
@@ -414,13 +378,9 @@ void JSObjectSetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned p
     
     jsObject->methodTable()->putByIndex(jsObject, exec, propertyIndex, jsValue, false);
     if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
         if (exception)
-            *exception = toRef(exec, exceptionValue);
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
     }
 }
 
@@ -437,13 +397,9 @@ bool JSObjectDeleteProperty(JSContextRef ctx, JSObjectRef object, JSStringRef pr
 
     bool result = jsObject->methodTable()->deleteProperty(jsObject, exec, propertyName->identifier(&exec->vm()));
     if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
         if (exception)
-            *exception = toRef(exec, exceptionValue);
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
     }
     return result;
 }
@@ -585,13 +541,9 @@ JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObject
 
     JSValueRef result = toRef(exec, call(exec, jsObject, callType, callData, jsThisObject, argList));
     if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
         if (exception)
-            *exception = toRef(exec, exceptionValue);
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
         result = 0;
     }
     return result;
@@ -626,13 +578,9 @@ JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size
         argList.append(toJS(exec, arguments[i]));
     JSObjectRef result = toRef(construct(exec, jsObject, constructType, constructData, argList));
     if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
         if (exception)
-            *exception = toRef(exec, exceptionValue);
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
         result = 0;
     }
     return result;
index 1a9c373..66ea7d8 100644 (file)
@@ -20,7 +20,7 @@
  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
 #include "config.h"
 #import <wtf/text/WTFString.h>
 #import <wtf/text/StringHash.h>
 
-#if ENABLE(REMOTE_INSPECTOR)
-#import "CallFrame.h"
-#import "JSGlobalObject.h"
-#import "JSGlobalObjectInspectorController.h"
-#endif
-
 #if JSC_OBJC_API_ENABLED
 
 NSString * const JSPropertyDescriptorWritableKey = @"writable";
@@ -635,14 +629,6 @@ JSContainerConvertor::Task JSContainerConvertor::take()
     return last;
 }
 
-#if ENABLE(REMOTE_INSPECTOR)
-static void reportExceptionToInspector(JSGlobalContextRef context, JSC::JSValue exception)
-{
-    JSC::ExecState* exec = toJS(context);
-    exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exception);
-}
-#endif
-
 static JSContainerConvertor::Task valueToObjectWithoutCopy(JSGlobalContextRef context, JSValueRef value)
 {
     if (!JSValueIsObject(context, value)) {
@@ -795,13 +781,8 @@ id valueToArray(JSGlobalContextRef context, JSValueRef value, JSValueRef* except
         return containerValueToObject(context, (JSContainerConvertor::Task){ value, [NSMutableArray array], ContainerArray});
 
     JSC::APIEntryShim shim(toJS(context));
-    if (!(JSValueIsNull(context, value) || JSValueIsUndefined(context, value))) {
-        JSC::JSObject* exceptionObject = JSC::createTypeError(toJS(context), ASCIILiteral("Cannot convert primitive to NSArray"));
-        *exception = toRef(exceptionObject);
-#if ENABLE(REMOTE_INSPECTOR)
-        reportExceptionToInspector(context, exceptionObject);
-#endif
-    }
+    if (!(JSValueIsNull(context, value) || JSValueIsUndefined(context, value)))
+        *exception = toRef(JSC::createTypeError(toJS(context), ASCIILiteral("Cannot convert primitive to NSArray")));
     return nil;
 }
 
@@ -817,13 +798,8 @@ id valueToDictionary(JSGlobalContextRef context, JSValueRef value, JSValueRef* e
         return containerValueToObject(context, (JSContainerConvertor::Task){ value, [NSMutableDictionary dictionary], ContainerDictionary});
 
     JSC::APIEntryShim shim(toJS(context));
-    if (!(JSValueIsNull(context, value) || JSValueIsUndefined(context, value))) {
-        JSC::JSObject* exceptionObject = JSC::createTypeError(toJS(context), ASCIILiteral("Cannot convert primitive to NSDictionary"));
-        *exception = toRef(exceptionObject);
-#if ENABLE(REMOTE_INSPECTOR)
-        reportExceptionToInspector(context, exceptionObject);
-#endif
-    }
+    if (!(JSValueIsNull(context, value) || JSValueIsUndefined(context, value)))
+        *exception = toRef(JSC::createTypeError(toJS(context), ASCIILiteral("Cannot convert primitive to NSDictionary")));
     return nil;
 }
 
index a7a4ac6..6f6f896 100644 (file)
@@ -20,7 +20,7 @@
  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
 #include "config.h"
 #include <mach-o/dyld.h>
 #endif
 
-#if ENABLE(REMOTE_INSPECTOR)
-#include "JSGlobalObjectInspectorController.h"
-#endif
-
 using namespace JSC;
 
 #if PLATFORM(MAC)
@@ -206,13 +202,9 @@ bool JSValueIsEqual(JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* ex
 
     bool result = JSValue::equal(exec, jsA, jsB); // false if an exception is thrown
     if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
         if (exception)
-            *exception = toRef(exec, exceptionValue);
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
     }
     return result;
 }
@@ -248,13 +240,9 @@ bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObject
         return false;
     bool result = jsConstructor->hasInstance(exec, jsValue); // false if an exception is thrown
     if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
         if (exception)
-            *exception = toRef(exec, exceptionValue);
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
     }
     return result;
 }
@@ -356,13 +344,9 @@ JSStringRef JSValueCreateJSONString(JSContextRef ctx, JSValueRef apiValue, unsig
     if (exception)
         *exception = 0;
     if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
         if (exception)
-            *exception = toRef(exec, exceptionValue);
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
         return 0;
     }
     return OpaqueJSString::create(result).leakRef();
@@ -394,13 +378,9 @@ double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception
 
     double number = jsValue.toNumber(exec);
     if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
         if (exception)
-            *exception = toRef(exec, exceptionValue);
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
         number = QNaN;
     }
     return number;
@@ -419,13 +399,9 @@ JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef*
     
     RefPtr<OpaqueJSString> stringRef(OpaqueJSString::create(jsValue.toString(exec)->value(exec)));
     if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
         if (exception)
-            *exception = toRef(exec, exceptionValue);
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
         stringRef.clear();
     }
     return stringRef.release().leakRef();
@@ -444,17 +420,13 @@ JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exce
     
     JSObjectRef objectRef = toRef(jsValue.toObject(exec));
     if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
         if (exception)
-            *exception = toRef(exec, exceptionValue);
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
         objectRef = 0;
     }
     return objectRef;
-}
+}    
 
 void JSValueProtect(JSContextRef ctx, JSValueRef value)
 {
index acca592..bf025cd 100644 (file)
@@ -1,3 +1,59 @@
+2014-02-22  Dan Bernstein  <mitz@apple.com>
+
+        REGRESSION (r164507): Crash beneath JSGlobalObjectInspectorController::reportAPIException at facebook.com, twitter.com, youtube.com
+        https://bugs.webkit.org/show_bug.cgi?id=129227
+
+        Reviewed by Eric Carlson.
+
+        Reverted r164507.
+
+        * API/JSBase.cpp:
+        (JSEvaluateScript):
+        (JSCheckScriptSyntax):
+        * API/JSObjectRef.cpp:
+        (JSObjectMakeFunction):
+        (JSObjectMakeArray):
+        (JSObjectMakeDate):
+        (JSObjectMakeError):
+        (JSObjectMakeRegExp):
+        (JSObjectGetProperty):
+        (JSObjectSetProperty):
+        (JSObjectGetPropertyAtIndex):
+        (JSObjectSetPropertyAtIndex):
+        (JSObjectDeleteProperty):
+        (JSObjectCallAsFunction):
+        (JSObjectCallAsConstructor):
+        * API/JSValue.mm:
+        (valueToArray):
+        (valueToDictionary):
+        * API/JSValueRef.cpp:
+        (JSValueIsEqual):
+        (JSValueIsInstanceOfConstructor):
+        (JSValueCreateJSONString):
+        (JSValueToNumber):
+        (JSValueToStringCopy):
+        (JSValueToObject):
+        * inspector/ConsoleMessage.cpp:
+        (Inspector::ConsoleMessage::ConsoleMessage):
+        (Inspector::ConsoleMessage::autogenerateMetadata):
+        * inspector/ConsoleMessage.h:
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
+        * inspector/JSGlobalObjectInspectorController.h:
+        * inspector/ScriptCallStack.cpp:
+        * inspector/ScriptCallStack.h:
+        * inspector/ScriptCallStackFactory.cpp:
+        (Inspector::createScriptCallStack):
+        (Inspector::createScriptCallStackForConsole):
+        (Inspector::createScriptCallStackFromException):
+        * inspector/ScriptCallStackFactory.h:
+        * inspector/agents/InspectorConsoleAgent.cpp:
+        (Inspector::InspectorConsoleAgent::enable):
+        (Inspector::InspectorConsoleAgent::addMessageToConsole):
+        (Inspector::InspectorConsoleAgent::count):
+        * inspector/agents/JSGlobalObjectDebuggerAgent.cpp:
+        (Inspector::JSGlobalObjectDebuggerAgent::breakpointActionLog):
+
 2014-02-22  Joseph Pecoraro  <pecoraro@apple.com>
 
         Remove some unreachable code (-Wunreachable-code)
index 336e554..b3a752a 100644 (file)
@@ -45,7 +45,7 @@
 
 namespace Inspector {
 
-ConsoleMessage::ConsoleMessage(MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned long requestIdentifier)
+ConsoleMessage::ConsoleMessage(bool canGenerateCallStack, MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned long requestIdentifier)
     : m_source(source)
     , m_type(type)
     , m_level(level)
@@ -56,9 +56,10 @@ ConsoleMessage::ConsoleMessage(MessageSource source, MessageType type, MessageLe
     , m_repeatCount(1)
     , m_requestId(IdentifiersFactory::requestId(requestIdentifier))
 {
+    autogenerateMetadata(canGenerateCallStack);
 }
 
-ConsoleMessage::ConsoleMessage(MessageSource source, MessageType type, MessageLevel level, const String& message, const String& url, unsigned line, unsigned column, JSC::ExecState* state, unsigned long requestIdentifier)
+ConsoleMessage::ConsoleMessage(bool canGenerateCallStack, MessageSource source, MessageType type, MessageLevel level, const String& message, const String& url, unsigned line, unsigned column, JSC::ExecState* state, unsigned long requestIdentifier)
     : m_source(source)
     , m_type(type)
     , m_level(level)
@@ -69,31 +70,30 @@ ConsoleMessage::ConsoleMessage(MessageSource source, MessageType type, MessageLe
     , m_repeatCount(1)
     , m_requestId(IdentifiersFactory::requestId(requestIdentifier))
 {
-    autogenerateMetadata(state);
+    autogenerateMetadata(canGenerateCallStack, state);
 }
 
-ConsoleMessage::ConsoleMessage(MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtr<ScriptCallStack> callStack, unsigned long requestIdentifier)
+ConsoleMessage::ConsoleMessage(bool, MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtr<ScriptCallStack> callStack, unsigned long requestIdentifier)
     : m_source(source)
     , m_type(type)
     , m_level(level)
     , m_message(message)
-    , m_url()
+    , m_arguments(nullptr)
     , m_line(0)
     , m_column(0)
     , m_repeatCount(1)
     , m_requestId(IdentifiersFactory::requestId(requestIdentifier))
 {
-    m_callStack = callStack;
-
-    const ScriptCallFrame* frame = m_callStack ? m_callStack->firstNonNativeCallFrame() : nullptr;
-    if (frame) {
-        m_url = frame->sourceURL();
-        m_line = frame->lineNumber();
-        m_column = frame->columnNumber();
+    if (callStack && callStack->size()) {
+        const ScriptCallFrame& frame = callStack->at(0);
+        m_url = frame.sourceURL();
+        m_line = frame.lineNumber();
+        m_column = frame.columnNumber();
     }
+    m_callStack = callStack;
 }
 
-ConsoleMessage::ConsoleMessage(MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtr<ScriptArguments> arguments, JSC::ExecState* state, unsigned long requestIdentifier)
+ConsoleMessage::ConsoleMessage(bool canGenerateCallStack, MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtr<ScriptArguments> arguments, JSC::ExecState* state, unsigned long requestIdentifier)
     : m_source(source)
     , m_type(type)
     , m_level(level)
@@ -105,30 +105,35 @@ ConsoleMessage::ConsoleMessage(MessageSource source, MessageType type, MessageLe
     , m_repeatCount(1)
     , m_requestId(IdentifiersFactory::requestId(requestIdentifier))
 {
-    autogenerateMetadata(state);
+    autogenerateMetadata(canGenerateCallStack, state);
 }
 
 ConsoleMessage::~ConsoleMessage()
 {
 }
 
-void ConsoleMessage::autogenerateMetadata(JSC::ExecState* state)
+// FIXME: Remove the generate without ExecState path. The caller should always provide an ExecState.
+void ConsoleMessage::autogenerateMetadata(bool /*canGenerateCallStack*/, JSC::ExecState* state)
 {
-    if (!state)
-        return;
-
     if (m_type == MessageType::EndGroup)
         return;
 
-    // FIXME: Should this really be using "for console" in the generic ConsoleMessage autogeneration? This can skip the first frame.
-    m_callStack = createScriptCallStackForConsole(state, ScriptCallStack::maxCallStackSizeToCapture);
+    if (state)
+        m_callStack = createScriptCallStackForConsole(state);
+    // else if (canGenerateCallStack)
+    //     m_callStack = createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture, true);
+    else
+        return;
 
-    if (const ScriptCallFrame* frame = m_callStack->firstNonNativeCallFrame()) {
-        m_url = frame->sourceURL();
-        m_line = frame->lineNumber();
-        m_column = frame->columnNumber();
+    if (m_callStack && m_callStack->size()) {
+        const ScriptCallFrame& frame = m_callStack->at(0);
+        m_url = frame.sourceURL();
+        m_line = frame.lineNumber();
+        m_column = frame.columnNumber();
         return;
     }
+
+    m_callStack.clear();
 }
 
 static Inspector::TypeBuilder::Console::ConsoleMessage::Source::Enum messageSourceValue(MessageSource source)
index a54aa8d..498eb1f 100644 (file)
@@ -51,10 +51,10 @@ class JS_EXPORT_PRIVATE ConsoleMessage {
     WTF_MAKE_NONCOPYABLE(ConsoleMessage);
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    ConsoleMessage(MessageSource, MessageType, MessageLevel, const String& message, unsigned long requestIdentifier = 0);
-    ConsoleMessage(MessageSource, MessageType, MessageLevel, const String& message, const String& url, unsigned line, unsigned column, JSC::ExecState* = nullptr, unsigned long requestIdentifier = 0);
-    ConsoleMessage(MessageSource, MessageType, MessageLevel, const String& message, PassRefPtr<ScriptCallStack>, unsigned long requestIdentifier = 0);
-    ConsoleMessage(MessageSource, MessageType, MessageLevel, const String& message, PassRefPtr<ScriptArguments>, JSC::ExecState*, unsigned long requestIdentifier = 0);
+    ConsoleMessage(bool canGenerateCallStack, MessageSource, MessageType, MessageLevel, const String& message, unsigned long requestIdentifier = 0);
+    ConsoleMessage(bool canGenerateCallStack, MessageSource, MessageType, MessageLevel, const String& message, const String& url, unsigned line, unsigned column, JSC::ExecState* = nullptr, unsigned long requestIdentifier = 0);
+    ConsoleMessage(bool canGenerateCallStack, MessageSource, MessageType, MessageLevel, const String& message, PassRefPtr<ScriptCallStack>, unsigned long requestIdentifier = 0);
+    ConsoleMessage(bool canGenerateCallStack, MessageSource, MessageType, MessageLevel, const String& message, PassRefPtr<ScriptArguments>, JSC::ExecState*, unsigned long requestIdentifier = 0);
     ~ConsoleMessage();
 
     void addToFrontend(InspectorConsoleFrontendDispatcher*, InjectedScriptManager*, bool generatePreview);
@@ -74,7 +74,7 @@ public:
     void clear();
 
 private:
-    void autogenerateMetadata(JSC::ExecState* = nullptr);
+    void autogenerateMetadata(bool canGenerateCallStack, JSC::ExecState* = nullptr);
 
     MessageSource m_source;
     MessageType m_type;
index 0288bcf..4dec996 100644 (file)
@@ -29,7 +29,6 @@
 #if ENABLE(INSPECTOR)
 
 #include "Completion.h"
-#include "ErrorHandlingScope.h"
 #include "InjectedScriptHost.h"
 #include "InjectedScriptManager.h"
 #include "InspectorAgent.h"
 #include "JSGlobalObjectConsoleAgent.h"
 #include "JSGlobalObjectDebuggerAgent.h"
 #include "JSGlobalObjectRuntimeAgent.h"
-#include "ScriptCallStack.h"
-#include "ScriptCallStackFactory.h"
-#include <cxxabi.h>
-#include <dlfcn.h>
-#include <execinfo.h>
 
 using namespace JSC;
 
@@ -58,8 +52,6 @@ JSGlobalObjectInspectorController::JSGlobalObjectInspectorController(JSGlobalObj
     auto consoleAgent = std::make_unique<JSGlobalObjectConsoleAgent>(m_injectedScriptManager.get());
     auto debuggerAgent = std::make_unique<JSGlobalObjectDebuggerAgent>(m_injectedScriptManager.get(), m_globalObject, consoleAgent.get());
 
-    m_consoleAgent = consoleAgent.get();
-
     runtimeAgent->setScriptDebugServer(&debuggerAgent->scriptDebugServer());
 
     m_agents.append(std::make_unique<InspectorAgent>());
@@ -109,51 +101,6 @@ void JSGlobalObjectInspectorController::dispatchMessageFromFrontend(const String
         m_inspectorBackendDispatcher->dispatch(message);
 }
 
-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, &frames);
-
-    void** stack = samples + framesToSkip;
-    int size = frames - framesToSkip;
-    for (int i = 0; i < size; ++i) {
-        const char* mangledName = nullptr;
-        char* cxaDemangled = nullptr;
-        Dl_info info;
-        if (dladdr(stack[i], &info) && info.dli_sname)
-            mangledName = info.dli_sname;
-        if (mangledName)
-            cxaDemangled = abi::__cxa_demangle(mangledName, nullptr, nullptr, nullptr);
-        if (mangledName || cxaDemangled)
-            callStack->append(ScriptCallFrame(cxaDemangled ? cxaDemangled : mangledName, ASCIILiteral("[native code]"), 0, 0));
-        else
-            callStack->append(ScriptCallFrame(ASCIILiteral("?"), ASCIILiteral("[native code]"), 0, 0));
-        free(cxaDemangled);
-    }
-}
-
-void JSGlobalObjectInspectorController::reportAPIException(ExecState* exec, JSValue exception)
-{
-    if (isTerminatedExecutionException(exception))
-        return;
-
-    ErrorHandlingScope errorScope(exec->vm());
-
-    RefPtr<ScriptCallStack> callStack = createScriptCallStackFromException(exec, exception, ScriptCallStack::maxCallStackSizeToCapture);
-    appendAPIBacktrace(callStack.get());
-
-    // FIXME: <http://webkit.org/b/115087> 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)->value(exec);
-    exec->clearException();
-
-    m_consoleAgent->addMessageToConsole(MessageSource::JS, MessageType::Log, MessageLevel::Error, errorMessage, callStack);
-}
-
 InspectorFunctionCallHandler JSGlobalObjectInspectorController::functionCallHandler() const
 {
     return JSC::call;
index 8266e59..377f40e 100644 (file)
 namespace JSC {
 class ExecState;
 class JSGlobalObject;
-class JSValue;
 }
 
 namespace Inspector {
 
 class InjectedScriptManager;
 class InspectorBackendDispatcher;
-class InspectorConsoleAgent;
 class InspectorFrontendChannel;
-class ScriptCallStack;
 
 class JSGlobalObjectInspectorController final : public InspectorEnvironment {
     WTF_MAKE_NONCOPYABLE(JSGlobalObjectInspectorController);
@@ -61,8 +58,6 @@ public:
 
     void globalObjectDestroyed();
 
-    void reportAPIException(JSC::ExecState*, JSC::JSValue exception);
-
     virtual bool developerExtrasEnabled() const override { return true; }
     virtual bool canAccessInspectedScriptState(JSC::ExecState*) const override { return true; }
     virtual InspectorFunctionCallHandler functionCallHandler() const override;
@@ -71,11 +66,8 @@ public:
     virtual void didCallInjectedScriptFunction(JSC::ExecState*) override { }
 
 private:
-    void appendAPIBacktrace(ScriptCallStack* callStack);
-
     JSC::JSGlobalObject& m_globalObject;
     std::unique_ptr<InjectedScriptManager> m_injectedScriptManager;
-    InspectorConsoleAgent* m_consoleAgent;
     InspectorAgentRegistry m_agents;
     InspectorFrontendChannel* m_inspectorFrontendChannel;
     RefPtr<InspectorBackendDispatcher> m_inspectorBackendDispatcher;
index 9b3cca1..2dd285f 100644 (file)
 
 namespace Inspector {
 
-PassRefPtr<ScriptCallStack> ScriptCallStack::create()
-{
-    return adoptRef(new ScriptCallStack);
-}
-
 PassRefPtr<ScriptCallStack> ScriptCallStack::create(Vector<ScriptCallFrame>& frames)
 {
     return adoptRef(new ScriptCallStack(frames));
 }
 
-ScriptCallStack::ScriptCallStack()
-{
-}
-
 ScriptCallStack::ScriptCallStack(Vector<ScriptCallFrame>& frames)
 {
     m_frames.swap(frames);
@@ -70,25 +61,6 @@ size_t ScriptCallStack::size() const
     return m_frames.size();
 }
 
-const ScriptCallFrame* ScriptCallStack::firstNonNativeCallFrame() const
-{
-    if (!m_frames.size())
-        return nullptr;
-
-    for (size_t i = 0; i < m_frames.size(); ++i) {
-        const ScriptCallFrame& frame = m_frames[i];
-        if (frame.sourceURL() != "[native code]")
-            return &frame;
-    }
-
-    return nullptr;
-}
-
-void ScriptCallStack::append(const ScriptCallFrame& frame)
-{
-    m_frames.append(frame);
-}
-
 bool ScriptCallStack::isEqual(ScriptCallStack* o) const
 {
     if (!o)
index 9c2a534..ddaa2bf 100644 (file)
@@ -47,7 +47,6 @@ class JS_EXPORT_PRIVATE ScriptCallStack : public RefCounted<ScriptCallStack> {
 public:
     static const size_t maxCallStackSizeToCapture = 200;
     
-    static PassRefPtr<ScriptCallStack> create();
     static PassRefPtr<ScriptCallStack> create(Vector<ScriptCallFrame>&);
 
     ~ScriptCallStack();
@@ -55,10 +54,6 @@ public:
     const ScriptCallFrame& at(size_t) const;
     size_t size() const;
 
-    const ScriptCallFrame* firstNonNativeCallFrame() const;
-
-    void append(const ScriptCallFrame&);
-
     bool isEqual(ScriptCallStack*) const;
 
 #if ENABLE(INSPECTOR)
@@ -66,7 +61,6 @@ public:
 #endif
 
 private:
-    ScriptCallStack();
     ScriptCallStack(Vector<ScriptCallFrame>&);
 
     Vector<ScriptCallFrame> m_frames;
index 2f06279..5637b4f 100644 (file)
@@ -83,25 +83,28 @@ private:
     size_t m_remainingCapacityForFrameCapture;
 };
 
-PassRefPtr<ScriptCallStack> createScriptCallStack(JSC::ExecState* exec, size_t maxStackSize)
+PassRefPtr<ScriptCallStack> createScriptCallStack(JSC::ExecState* exec, size_t maxStackSize, bool emptyIsAllowed)
 {
-    if (!exec)
-        return ScriptCallStack::create();
-
     Vector<ScriptCallFrame> frames;
 
-    CallFrame* frame = exec->vm().topCallFrame;
-    CreateScriptCallStackFunctor functor(false, frames, maxStackSize);
-    frame->iterate(functor);
+    if (exec) {
+        CallFrame* frame = exec->vm().topCallFrame;
+        CreateScriptCallStackFunctor functor(false, frames, maxStackSize);
+        frame->iterate(functor);
+    }
+
+    if (frames.isEmpty() && !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 "undefined".
+        frames.append(ScriptCallFrame(ASCIILiteral("undefined"), ASCIILiteral("undefined"), 0, 0));
+    }
 
     return ScriptCallStack::create(frames);
 }
 
-PassRefPtr<ScriptCallStack> createScriptCallStackForConsole(JSC::ExecState* exec, size_t maxStackSize)
+PassRefPtr<ScriptCallStack> createScriptCallStack(JSC::ExecState* exec, size_t maxStackSize)
 {
-    if (!exec)
-        return ScriptCallStack::create();
-
     Vector<ScriptCallFrame> frames;
 
     CallFrame* frame = exec->vm().topCallFrame;
@@ -116,16 +119,10 @@ PassRefPtr<ScriptCallStack> createScriptCallStackForConsole(JSC::ExecState* exec
     return ScriptCallStack::create(frames);
 }
 
-static void extractSourceInformationFromException(JSC::ExecState* exec, JSObject* exceptionObject, int* lineNumber, int* columnNumber, String* sourceURL)
+PassRefPtr<ScriptCallStack> createScriptCallStackForConsole(JSC::ExecState* exec)
 {
-    // FIXME: <http://webkit.org/b/115087> Web Inspector: Should not need to evaluate JavaScript handling exceptions
-    JSValue lineValue = exceptionObject->getDirect(exec->vm(), Identifier(exec, "line"));
-    *lineNumber = lineValue && lineValue.isNumber() ? int(lineValue.toNumber(exec)) : 0;
-    JSValue columnValue = exceptionObject->getDirect(exec->vm(), Identifier(exec, "column"));
-    *columnNumber = columnValue && columnValue.isNumber() ? int(columnValue.toNumber(exec)) : 0;
-    JSValue sourceURLValue = exceptionObject->getDirect(exec->vm(), Identifier(exec, "sourceURL"));
-    *sourceURL = sourceURLValue && sourceURLValue.isString() ? sourceURLValue.toString(exec)->value(exec) : String("undefined");
-    exec->clearException();
+    // FIXME: Caller should use createScriptCallStack alternative with the exec and appropriate max.
+    return createScriptCallStack(exec, ScriptCallStack::maxCallStackSizeToCapture);
 }
 
 PassRefPtr<ScriptCallStack> createScriptCallStackFromException(JSC::ExecState* exec, JSC::JSValue& exception, size_t maxStackSize)
@@ -133,28 +130,29 @@ PassRefPtr<ScriptCallStack> createScriptCallStackFromException(JSC::ExecState* e
     Vector<ScriptCallFrame> frames;
     RefCountedArray<StackFrame> stackTrace = exec->vm().exceptionStack();
     for (size_t i = 0; i < stackTrace.size() && i < maxStackSize; i++) {
+        if (!stackTrace[i].callee && frames.size())
+            break;
+
         unsigned line;
         unsigned column;
         stackTrace[i].computeLineAndColumn(line, column);
         String functionName = stackTrace[i].friendlyFunctionName(exec);
-        frames.append(ScriptCallFrame(functionName, stackTrace[i].friendlySourceURL(), line, column));
+        frames.append(ScriptCallFrame(functionName, stackTrace[i].sourceURL, line, column));
     }
 
-    // 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, &lineNumber, &columnNumber, &exceptionSourceURL);
-            frames.append(ScriptCallFrame(String(), exceptionSourceURL, lineNumber, columnNumber));
-        } else {
-            if (stackTrace[0].sourceURL.isEmpty()) {
-                const ScriptCallFrame& firstCallFrame = frames.first();
-                extractSourceInformationFromException(exec, exceptionObject, &lineNumber, &columnNumber, &exceptionSourceURL);
-                frames[0] = ScriptCallFrame(firstCallFrame.functionName(), exceptionSourceURL, lineNumber, columnNumber);
-            }
+    // FIXME: <http://webkit.org/b/115087> 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() > 0) {
+        const ScriptCallFrame& firstCallFrame = frames.first();
+        JSObject* exceptionObject = exception.toObject(exec);
+        if (exception.isObject() && firstCallFrame.sourceURL().isEmpty()) {
+            JSValue lineValue = exceptionObject->getDirect(exec->vm(), Identifier(exec, "line"));
+            int lineNumber = lineValue && lineValue.isNumber() ? int(lineValue.toNumber(exec)) : 0;
+            JSValue columnValue = exceptionObject->getDirect(exec->vm(), Identifier(exec, "column"));
+            int columnNumber = columnValue && columnValue.isNumber() ? int(columnValue.toNumber(exec)) : 0;
+            JSValue sourceURLValue = exceptionObject->getDirect(exec->vm(), Identifier(exec, "sourceURL"));
+            String exceptionSourceURL = sourceURLValue && sourceURLValue.isString() ? sourceURLValue.toString(exec)->value(exec) : ASCIILiteral("undefined");
+            frames[0] = ScriptCallFrame(firstCallFrame.functionName(), exceptionSourceURL, lineNumber, columnNumber);
         }
     }
 
index 07c1586..7ce9c90 100644 (file)
@@ -45,8 +45,9 @@ class ScriptArguments;
 class ScriptCallStack;
 
 // FIXME: The subtle differences between these should be eliminated.
+JS_EXPORT_PRIVATE PassRefPtr<ScriptCallStack> createScriptCallStack(JSC::ExecState*, size_t maxStackSize, bool emptyIsAllowed);
 JS_EXPORT_PRIVATE PassRefPtr<ScriptCallStack> createScriptCallStack(JSC::ExecState*, size_t maxStackSize);
-JS_EXPORT_PRIVATE PassRefPtr<ScriptCallStack> createScriptCallStackForConsole(JSC::ExecState*, size_t maxStackSize);
+JS_EXPORT_PRIVATE PassRefPtr<ScriptCallStack> createScriptCallStackForConsole(JSC::ExecState*);
 JS_EXPORT_PRIVATE PassRefPtr<ScriptCallStack> createScriptCallStackFromException(JSC::ExecState*, JSC::JSValue& exception, size_t maxStackSize);
 JS_EXPORT_PRIVATE PassRefPtr<ScriptArguments> createScriptArguments(JSC::ExecState*, unsigned skipArgumentCount);
 
index 37b2227..72f60c1 100644 (file)
@@ -80,7 +80,7 @@ void InspectorConsoleAgent::enable(ErrorString*)
     m_enabled = true;
 
     if (m_expiredConsoleMessageCount) {
-        ConsoleMessage expiredMessage(MessageSource::Other, MessageType::Log, MessageLevel::Warning, String::format("%d console messages are not shown.", m_expiredConsoleMessageCount));
+        ConsoleMessage expiredMessage(!isWorkerAgent(), MessageSource::Other, MessageType::Log, MessageLevel::Warning, String::format("%d console messages are not shown.", m_expiredConsoleMessageCount));
         expiredMessage.addToFrontend(m_frontendDispatcher.get(), m_injectedScriptManager, false);
     }
 
@@ -128,7 +128,7 @@ void InspectorConsoleAgent::addMessageToConsole(MessageSource source, MessageTyp
         clearMessages(&error);
     }
 
-    addConsoleMessage(std::make_unique<ConsoleMessage>(source, type, level, message, callStack, requestIdentifier));
+    addConsoleMessage(std::make_unique<ConsoleMessage>(!isWorkerAgent(), source, type, level, message, callStack, requestIdentifier));
 }
 
 void InspectorConsoleAgent::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, const String& message, JSC::ExecState* state, PassRefPtr<ScriptArguments> arguments, unsigned long requestIdentifier)
@@ -141,7 +141,7 @@ void InspectorConsoleAgent::addMessageToConsole(MessageSource source, MessageTyp
         clearMessages(&error);
     }
 
-    addConsoleMessage(std::make_unique<ConsoleMessage>(source, type, level, message, arguments, state, requestIdentifier));
+    addConsoleMessage(std::make_unique<ConsoleMessage>(!isWorkerAgent(), source, type, level, message, arguments, state, requestIdentifier));
 }
 
 void InspectorConsoleAgent::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, const String& message, const String& scriptID, unsigned lineNumber, unsigned columnNumber, JSC::ExecState* state, unsigned long requestIdentifier)
@@ -154,7 +154,8 @@ void InspectorConsoleAgent::addMessageToConsole(MessageSource source, MessageTyp
         clearMessages(&error);
     }
 
-    addConsoleMessage(std::make_unique<ConsoleMessage>(source, type, level, message, scriptID, lineNumber, columnNumber, state, requestIdentifier));
+    bool canGenerateCallStack = !isWorkerAgent() && m_frontendDispatcher;
+    addConsoleMessage(std::make_unique<ConsoleMessage>(canGenerateCallStack, source, type, level, message, scriptID, lineNumber, columnNumber, state, requestIdentifier));
 }
 
 Vector<unsigned> InspectorConsoleAgent::consoleMessageArgumentCounts() const
@@ -196,7 +197,7 @@ void InspectorConsoleAgent::stopTiming(const String& title, PassRefPtr<ScriptCal
 
 void InspectorConsoleAgent::count(JSC::ExecState* state, PassRefPtr<ScriptArguments> arguments)
 {
-    RefPtr<ScriptCallStack> callStack(createScriptCallStackForConsole(state, ScriptCallStack::maxCallStackSizeToCapture));
+    RefPtr<ScriptCallStack> callStack(createScriptCallStackForConsole(state));
     const ScriptCallFrame& lastCaller = callStack->at(0);
     // Follow Firebug's behavior of counting with null and undefined title in
     // the same bucket as no argument
index c087e81..2e1750b 100644 (file)
@@ -69,7 +69,7 @@ InjectedScript JSGlobalObjectDebuggerAgent::injectedScriptForEval(ErrorString* e
 
 void JSGlobalObjectDebuggerAgent::breakpointActionLog(JSC::ExecState* exec, const String& message)
 {
-    m_consoleAgent->addMessageToConsole(MessageSource::JS, MessageType::Log, MessageLevel::Log, message, createScriptCallStack(exec, ScriptCallStack::maxCallStackSizeToCapture), 0);
+    m_consoleAgent->addMessageToConsole(MessageSource::JS, MessageType::Log, MessageLevel::Log, message, createScriptCallStack(exec, ScriptCallStack::maxCallStackSizeToCapture, true), 0);
 }
 
 } // namespace Inspector
index 9e73c03..71e82f1 100644 (file)
@@ -1,3 +1,31 @@
+2014-02-22  Dan Bernstein  <mitz@apple.com>
+
+        REGRESSION (r164507): Crash beneath JSGlobalObjectInspectorController::reportAPIException at facebook.com, twitter.com, youtube.com
+        https://bugs.webkit.org/show_bug.cgi?id=129227
+
+        Reviewed by Eric Carlson.
+
+        Reverted r164507.
+
+        * bindings/js/JSDOMBinding.cpp:
+        (WebCore::reportException):
+        * 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):
+
 2014-02-22  Joseph Pecoraro  <pecoraro@apple.com>
 
         Remove some unreachable code (-Wunreachable-code)
index 8badc84..0640ab8 100644 (file)
@@ -171,10 +171,20 @@ void reportException(ExecState* exec, JSValue exception, CachedScript* cachedScr
     int lineNumber = 0;
     int columnNumber = 0;
     String exceptionSourceURL;
-    if (const ScriptCallFrame* callFrame = callStack->firstNonNativeCallFrame()) {
-        lineNumber = callFrame->lineNumber();
-        columnNumber = callFrame->columnNumber();
-        exceptionSourceURL = callFrame->sourceURL();
+    if (callStack->size()) {
+        const ScriptCallFrame& frame = callStack->at(0);
+        lineNumber = frame.lineNumber();
+        columnNumber = frame.columnNumber();
+        exceptionSourceURL = frame.sourceURL();
+    } else {
+        // There may not be an exceptionStack for a <script> SyntaxError. Fallback to getting at least the line and sourceURL from the exception.
+        JSObject* exceptionObject = exception.toObject(exec);
+        JSValue lineValue = exceptionObject->getDirect(exec->vm(), Identifier(exec, "line"));
+        lineNumber = lineValue && lineValue.isNumber() ? int(lineValue.toNumber(exec)) : 0;
+        JSValue columnValue = exceptionObject->getDirect(exec->vm(), Identifier(exec, "column"));
+        columnNumber = columnValue && columnValue.isNumber() ? int(columnValue.toNumber(exec)) : 0;
+        JSValue sourceURLValue = exceptionObject->getDirect(exec->vm(), Identifier(exec, "sourceURL"));
+        exceptionSourceURL = sourceURLValue && sourceURLValue.isString() ? sourceURLValue.toString(exec)->value(exec) : ASCIILiteral("undefined");
     }
 
     String errorMessage;
index a6548b6..89e5cf4 100644 (file)
@@ -439,7 +439,7 @@ void InspectorResourceAgent::didScheduleStyleRecalculation(Document* document)
 
 PassRefPtr<Inspector::TypeBuilder::Network::Initiator> InspectorResourceAgent::buildInitiatorObject(Document* document)
 {
-    RefPtr<ScriptCallStack> stackTrace = createScriptCallStack(JSMainThreadExecState::currentState(), ScriptCallStack::maxCallStackSizeToCapture);
+    RefPtr<ScriptCallStack> stackTrace = createScriptCallStack(JSMainThreadExecState::currentState(), ScriptCallStack::maxCallStackSizeToCapture, true);
     if (stackTrace && stackTrace->size() > 0) {
         RefPtr<Inspector::TypeBuilder::Network::Initiator> initiatorObject = Inspector::TypeBuilder::Network::Initiator::create()
             .setType(Inspector::TypeBuilder::Network::Initiator::Type::Script);
index b536226..e4670cd 100644 (file)
@@ -117,7 +117,7 @@ void PageDebuggerAgent::unmuteConsole()
 
 void PageDebuggerAgent::breakpointActionLog(JSC::ExecState* exec, const String& message)
 {
-    m_pageAgent->page()->console().addMessage(MessageSource::JS, MessageLevel::Log, message, createScriptCallStack(exec, ScriptCallStack::maxCallStackSizeToCapture));
+    m_pageAgent->page()->console().addMessage(MessageSource::JS, MessageLevel::Log, message, createScriptCallStack(exec, ScriptCallStack::maxCallStackSizeToCapture, true));
 }
 
 InjectedScript PageDebuggerAgent::injectedScriptForEval(ErrorString* errorString, const int* executionContextId)
index 2d62276..d9da743 100644 (file)
@@ -57,7 +57,7 @@ PassRefPtr<InspectorObject> TimelineRecordFactory::createGenericRecord(double st
     record->setNumber("startTime", startTime);
 
     if (maxCallStackDepth) {
-        RefPtr<ScriptCallStack> stackTrace = createScriptCallStack(JSMainThreadExecState::currentState(), maxCallStackDepth);
+        RefPtr<ScriptCallStack> stackTrace = createScriptCallStack(JSMainThreadExecState::currentState(), maxCallStackDepth, true);
         if (stackTrace && stackTrace->size())
             record->setValue("stackTrace", stackTrace->buildInspectorArray());
     }
index 790d703..e73a6ed 100644 (file)
@@ -77,7 +77,7 @@ static void internalAddMessage(Page* page, MessageType type, MessageLevel level,
         return;
 
     size_t stackSize = printTrace ? ScriptCallStack::maxCallStackSizeToCapture : 1;
-    RefPtr<ScriptCallStack> callStack(createScriptCallStackForConsole(state, stackSize));
+    RefPtr<ScriptCallStack> callStack(createScriptCallStack(state, stackSize));
     const ScriptCallFrame& lastCaller = callStack->at(0);
 
     String message;
@@ -203,7 +203,7 @@ void Console::profile(JSC::ExecState* state, const String& title)
 
     ScriptProfiler::start(state, resolvedTitle);
 
-    RefPtr<ScriptCallStack> callStack(createScriptCallStackForConsole(state, 1));
+    RefPtr<ScriptCallStack> callStack(createScriptCallStack(state, 1));
     const ScriptCallFrame& lastCaller = callStack->at(0);
     InspectorInstrumentation::addStartProfilingMessageToConsole(page, resolvedTitle, lastCaller.lineNumber(), lastCaller.columnNumber(), lastCaller.sourceURL());
 }
@@ -222,7 +222,7 @@ void Console::profileEnd(JSC::ExecState* state, const String& title)
         return;
 
     m_profiles.append(profile);
-    RefPtr<ScriptCallStack> callStack(createScriptCallStackForConsole(state, 1));
+    RefPtr<ScriptCallStack> callStack(createScriptCallStack(state, 1));
     InspectorInstrumentation::addProfile(page, profile, callStack);
 }
 
@@ -233,7 +233,7 @@ void Console::time(const String& title)
 
 void Console::timeEnd(JSC::ExecState* state, const String& title)
 {
-    RefPtr<ScriptCallStack> callStack(createScriptCallStackForConsole(state, 1));
+    RefPtr<ScriptCallStack> callStack(createScriptCallStackForConsole(state));
     InspectorInstrumentation::stopConsoleTiming(m_frame, title, callStack.release());
 }
 
index 62365df..1fa112a 100644 (file)
@@ -171,6 +171,15 @@ FeatureObserver::Feature getFeatureObserverType(ContentSecurityPolicy::HeaderTyp
     return FeatureObserver::NumberOfFeatures;
 }
 
+const ScriptCallFrame& getFirstNonNativeFrame(PassRefPtr<ScriptCallStack> stack)
+{
+    int frameNumber = 0;
+    if (!stack->at(0).lineNumber() && stack->size() > 1 && stack->at(1).lineNumber())
+        frameNumber = 1;
+
+    return stack->at(frameNumber);
+}
+
 } // namespace
 
 static bool skipExactly(const UChar*& position, const UChar* end, UChar delimiter)
@@ -1718,12 +1727,16 @@ static void gatherSecurityPolicyViolationEventData(SecurityPolicyViolationEventI
     init.sourceFile = String();
     init.lineNumber = 0;
 
-    RefPtr<ScriptCallStack> stack = createScriptCallStack(JSMainThreadExecState::currentState(), 2);
-    const ScriptCallFrame* callFrame = stack->firstNonNativeCallFrame();
-    if (callFrame && callFrame->lineNumber()) {
-        URL source = URL(URL(), callFrame->sourceURL());
+    RefPtr<ScriptCallStack> stack = createScriptCallStack(JSMainThreadExecState::currentState(), 2, false);
+    if (!stack)
+        return;
+
+    const ScriptCallFrame& callFrame = getFirstNonNativeFrame(stack);
+
+    if (callFrame.lineNumber()) {
+        URL source = URL(ParsedURLString, callFrame.sourceURL());
         init.sourceFile = stripURLForUseInReport(document, source);
-        init.lineNumber = callFrame->lineNumber();
+        init.lineNumber = callFrame.lineNumber();
     }
 }
 #endif
@@ -1764,28 +1777,31 @@ void ContentSecurityPolicy::reportViolation(const String& directiveText, const S
     // harmless information.
 
     RefPtr<InspectorObject> cspReport = InspectorObject::create();
-    cspReport->setString(ASCIILiteral("document-uri"), document->url().strippedForUseAsReferrer());
-    cspReport->setString(ASCIILiteral("referrer"), document->referrer());
-    cspReport->setString(ASCIILiteral("violated-directive"), directiveText);
+    cspReport->setString("document-uri", document->url().strippedForUseAsReferrer());
+    cspReport->setString("referrer", document->referrer());
+    cspReport->setString("violated-directive", directiveText);
 #if ENABLE(CSP_NEXT)
     if (experimentalFeaturesEnabled())
-        cspReport->setString(ASCIILiteral("effective-directive"), effectiveDirective);
+        cspReport->setString("effective-directive", effectiveDirective);
 #else
     UNUSED_PARAM(effectiveDirective);
 #endif
-    cspReport->setString(ASCIILiteral("original-policy"), header);
-    cspReport->setString(ASCIILiteral("blocked-uri"), stripURLForUseInReport(document, blockedURL));
-
-    RefPtr<ScriptCallStack> stack = createScriptCallStack(JSMainThreadExecState::currentState(), 2);
-    const ScriptCallFrame* callFrame = stack->firstNonNativeCallFrame();
-    if (callFrame && callFrame->lineNumber()) {
-        URL source = URL(URL(), callFrame->sourceURL());
-        cspReport->setString(ASCIILiteral("source-file"), stripURLForUseInReport(document, source));
-        cspReport->setNumber(ASCIILiteral("line-number"), callFrame->lineNumber());
+    cspReport->setString("original-policy", header);
+    cspReport->setString("blocked-uri", stripURLForUseInReport(document, blockedURL));
+
+    RefPtr<ScriptCallStack> stack = createScriptCallStack(JSMainThreadExecState::currentState(), 2, false);
+    if (stack) {
+        const ScriptCallFrame& callFrame = getFirstNonNativeFrame(stack);
+
+        if (callFrame.lineNumber()) {
+            URL source = URL(ParsedURLString, callFrame.sourceURL());
+            cspReport->setString("source-file", stripURLForUseInReport(document, source));
+            cspReport->setNumber("line-number", callFrame.lineNumber());
+        }
     }
 
     RefPtr<InspectorObject> reportObject = InspectorObject::create();
-    reportObject->setObject(ASCIILiteral("csp-report"), cspReport.release());
+    reportObject->setObject("csp-report", cspReport.release());
 
     RefPtr<FormData> report = FormData::create(reportObject->toJSONString().utf8());
 
index e730b08..4fa4330 100644 (file)
@@ -846,7 +846,7 @@ void DOMWindow::postMessage(PassRefPtr<SerializedScriptValue> message, const Mes
     // Capture stack trace only when inspector front-end is loaded as it may be time consuming.
     RefPtr<ScriptCallStack> stackTrace;
     if (InspectorInstrumentation::consoleAgentEnabled(sourceDocument))
-        stackTrace = createScriptCallStack(JSMainThreadExecState::currentState(), ScriptCallStack::maxCallStackSizeToCapture);
+        stackTrace = createScriptCallStack(JSMainThreadExecState::currentState(), ScriptCallStack::maxCallStackSizeToCapture, true);
 
     // Schedule the message.
     PostMessageTimer* timer = new PostMessageTimer(this, message, sourceOrigin, &source, std::move(channels), target.get(), stackTrace.release());
index 3e2fef2..df8bbd9 100644 (file)
@@ -1,3 +1,16 @@
+2014-02-22  Dan Bernstein  <mitz@apple.com>
+
+        REGRESSION (r164507): Crash beneath JSGlobalObjectInspectorController::reportAPIException at facebook.com, twitter.com, youtube.com
+        https://bugs.webkit.org/show_bug.cgi?id=129227
+
+        Reviewed by Eric Carlson.
+
+        Reverted r164507.
+
+        * UserInterface/Views/ConsoleMessageImpl.js:
+        (WebInspector.ConsoleMessageImpl.prototype._formatMessage):
+        (WebInspector.ConsoleMessageImpl.prototype._populateStackTraceTreeElement):
+
 2014-02-21  Timothy Hatcher  <timothy@apple.com>
 
         Organize WebInspectorUI/UserInterface into sub-directories.
index a25a045..a61ffc2 100644 (file)
@@ -109,11 +109,10 @@ WebInspector.ConsoleMessageImpl.prototype = {
         }
 
         if (this.source !== WebInspector.ConsoleMessage.MessageSource.Network || this._request) {
-            var firstNonNativeCallFrame = this._firstNonNativeCallFrame();
-            if (firstNonNativeCallFrame) {
-                var urlElement = this._linkifyCallFrame(firstNonNativeCallFrame);
+            if (this._stackTrace && this._stackTrace.length && this._stackTrace[0].url) {
+                var urlElement = this._linkifyCallFrame(this._stackTrace[0]);
                 this._formattedMessage.appendChild(urlElement);
-            } else if (this.url && !this._shouldHideURL(this.url)) {
+            } else if (this.url && this.url !== "undefined") {
                 var urlElement = this._linkifyLocation(this.url, this.line, this.column);
                 this._formattedMessage.appendChild(urlElement);
             }
@@ -146,26 +145,6 @@ WebInspector.ConsoleMessageImpl.prototype = {
         return !!this._stackTrace && this._stackTrace.length && (this.source === WebInspector.ConsoleMessage.MessageSource.Network || this.level === WebInspector.ConsoleMessage.MessageLevel.Error || this.type === WebInspector.ConsoleMessage.MessageType.Trace);
     },
 
-    _shouldHideURL: function(url)
-    {
-        return url === "undefined" || url === "[native code]";
-    },
-
-    _firstNonNativeCallFrame: function()
-    {
-        if (!this._stackTrace)
-            return null;
-
-        for (var i = 0; i < this._stackTrace.length; i++) {
-            var frame = this._stackTrace[i];
-            if (!frame.url || frame.url === "[native code]")
-                continue;
-            return frame;
-        }
-
-        return null;
-    },
-
     get message()
     {
         // force message formatting
@@ -547,7 +526,7 @@ WebInspector.ConsoleMessageImpl.prototype = {
             messageTextElement.appendChild(document.createTextNode(functionName));
             content.appendChild(messageTextElement);
 
-            if (frame.url && !this._shouldHideURL(frame.url)) {
+            if (frame.url) {
                 var urlElement = this._linkifyCallFrame(frame);
                 content.appendChild(urlElement);
             }