Web Inspector: no need to allocate protocolErrors array for every dispatched backend...
authorbburg@apple.com <bburg@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 26 Aug 2015 14:34:38 +0000 (14:34 +0000)
committerbburg@apple.com <bburg@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 26 Aug 2015 14:34:38 +0000 (14:34 +0000)
https://bugs.webkit.org/show_bug.cgi?id=146466

Reviewed by Joseph Pecoraro.

Source/JavaScriptCore:

Clean up some of the backend dispatcher code, with a focus on eliminating useless allocations
of objects in the common case when no protocol errors happen. This is done by saving the
current id of each request as it is being processed by the backend dispatcher, and tagging any
subsequent errors with that id. This also means we don't have to thread the requestId except
in the async command code path.

This patch also lifts some common code shared between all generated backend command
implementatations into the per-domain dispatch method instead. This reduces generated code size.

To be consistent, this patch standardizes on calling the id of a backend message its 'requestId'.
Requests can be handled synchronously or asynchronously (triggered via the 'async' property).

No new tests, covered by existing protocol tests.

* inspector/InspectorBackendDispatcher.cpp:
(Inspector::BackendDispatcher::CallbackBase::CallbackBase): Split the two code paths for reporting
success and failure.

(Inspector::BackendDispatcher::CallbackBase::sendFailure):
(Inspector::BackendDispatcher::CallbackBase::sendSuccess): Renamed from sendIfActive.
(Inspector::BackendDispatcher::dispatch): Reset counters and current requestId before dispatching.
No need to manually thread the requestId to all reportProtocolError calls.

(Inspector::BackendDispatcher::hasProtocolErrors): Added.
(Inspector::BackendDispatcher::sendResponse):
(Inspector::BackendDispatcher::sendPendingErrors): Send any saved protocol errors to the frontend.
Always send a 'data' member with all of the errors, even if there's just one. We might want to add
more information about errors later.

(Inspector::BackendDispatcher::reportProtocolError): Enqueue a protocol error to be sent later.
(Inspector::BackendDispatcher::getPropertyValue): Remove useless type parameters and nuke most of
the type conversion methods. Use std::function types instead of function pointer types.

(Inspector::castToInteger): Added.
(Inspector::castToNumber): Added.
(Inspector::BackendDispatcher::getInteger):
(Inspector::BackendDispatcher::getDouble):
(Inspector::BackendDispatcher::getString):
(Inspector::BackendDispatcher::getBoolean):
(Inspector::BackendDispatcher::getObject):
(Inspector::BackendDispatcher::getArray):
(Inspector::BackendDispatcher::getValue):
(Inspector::getPropertyValue): Deleted.
(Inspector::AsMethodBridges::asInteger): Deleted.
(Inspector::AsMethodBridges::asDouble): Deleted.
(Inspector::AsMethodBridges::asString): Deleted.
(Inspector::AsMethodBridges::asBoolean): Deleted.
(Inspector::AsMethodBridges::asObject): Deleted.
(Inspector::AsMethodBridges::asArray): Deleted.
(Inspector::AsMethodBridges::asValue): Deleted.
* inspector/InspectorBackendDispatcher.h:
* inspector/scripts/codegen/cpp_generator_templates.py: Extract 'params' object in domain dispatch method.
Omit requestIds where possible. Convert dispatch tables to use NeverDestroyed. Check the protocol error count
to decide whether to abort the dispatch or not, rather than allocating our own errors array.

* inspector/scripts/codegen/cpp_generator_templates.py:
(void):
* inspector/scripts/codegen/generate_cpp_backend_dispatcher_header.py: Revert to passing RefPtr<InspectorObject>
since parameters are now being passed rather than the message object. Some commands do not require parameters.
* inspector/scripts/codegen/generate_cpp_backend_dispatcher_implementation.py:
(CppBackendDispatcherImplementationGenerator.generate_output):
(CppBackendDispatcherImplementationGenerator._generate_small_dispatcher_switch_implementation_for_domain):
(CppBackendDispatcherImplementationGenerator._generate_dispatcher_implementation_for_command):
* inspector/scripts/codegen/generate_objc_backend_dispatcher_header.py:
(ObjCBackendDispatcherHeaderGenerator._generate_objc_handler_declaration_for_command):
* inspector/scripts/codegen/generate_objc_backend_dispatcher_implementation.py:
(ObjCConfigurationImplementationGenerator._generate_handler_implementation_for_command):
(ObjCConfigurationImplementationGenerator._generate_success_block_for_command):
* inspector/scripts/codegen/objc_generator_templates.py:

Rebaseline some protocol generator tests.
* inspector/scripts/tests/expected/commands-with-async-attribute.json-result:
* inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result:
* inspector/scripts/tests/expected/domains-with-varying-command-sizes.json-result:
* inspector/scripts/tests/expected/enum-values.json-result:
* inspector/scripts/tests/expected/events-with-optional-parameters.json-result:
* inspector/scripts/tests/expected/generate-domains-with-feature-guards.json-result:
* inspector/scripts/tests/expected/same-type-id-different-domain.json-result:
* inspector/scripts/tests/expected/shadowed-optional-type-setters.json-result:
* inspector/scripts/tests/expected/type-declaration-aliased-primitive-type.json-result:
* inspector/scripts/tests/expected/type-declaration-array-type.json-result:
* inspector/scripts/tests/expected/type-declaration-enum-type.json-result:
* inspector/scripts/tests/expected/type-declaration-object-type.json-result:
* inspector/scripts/tests/expected/type-requiring-runtime-casts.json-result:

Source/WebInspectorUI:

* UserInterface/TestStub.html: Fix a typo, this property exists on ProtocolTest.

LayoutTests:

* inspector/protocol/backend-dispatcher-argument-errors-expected.txt:
* inspector/protocol/backend-dispatcher-argument-errors.html:
Stringify the 'data' member before dumping, since it now contains JSON. Rebaseline it.

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

27 files changed:
LayoutTests/ChangeLog
LayoutTests/inspector/protocol/backend-dispatcher-argument-errors-expected.txt
LayoutTests/inspector/protocol/backend-dispatcher-argument-errors.html
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/inspector/InspectorBackendDispatcher.cpp
Source/JavaScriptCore/inspector/InspectorBackendDispatcher.h
Source/JavaScriptCore/inspector/scripts/codegen/cpp_generator_templates.py
Source/JavaScriptCore/inspector/scripts/codegen/generate_cpp_backend_dispatcher_header.py
Source/JavaScriptCore/inspector/scripts/codegen/generate_cpp_backend_dispatcher_implementation.py
Source/JavaScriptCore/inspector/scripts/codegen/generate_objc_backend_dispatcher_header.py
Source/JavaScriptCore/inspector/scripts/codegen/generate_objc_backend_dispatcher_implementation.py
Source/JavaScriptCore/inspector/scripts/codegen/objc_generator_templates.py
Source/JavaScriptCore/inspector/scripts/tests/expected/commands-with-async-attribute.json-result
Source/JavaScriptCore/inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result
Source/JavaScriptCore/inspector/scripts/tests/expected/domains-with-varying-command-sizes.json-result
Source/JavaScriptCore/inspector/scripts/tests/expected/enum-values.json-result
Source/JavaScriptCore/inspector/scripts/tests/expected/events-with-optional-parameters.json-result
Source/JavaScriptCore/inspector/scripts/tests/expected/generate-domains-with-feature-guards.json-result
Source/JavaScriptCore/inspector/scripts/tests/expected/same-type-id-different-domain.json-result
Source/JavaScriptCore/inspector/scripts/tests/expected/shadowed-optional-type-setters.json-result
Source/JavaScriptCore/inspector/scripts/tests/expected/type-declaration-aliased-primitive-type.json-result
Source/JavaScriptCore/inspector/scripts/tests/expected/type-declaration-array-type.json-result
Source/JavaScriptCore/inspector/scripts/tests/expected/type-declaration-enum-type.json-result
Source/JavaScriptCore/inspector/scripts/tests/expected/type-declaration-object-type.json-result
Source/JavaScriptCore/inspector/scripts/tests/expected/type-requiring-runtime-casts.json-result
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/UserInterface/TestStub.html

index 13daab2..8559d0e 100644 (file)
@@ -1,3 +1,14 @@
+2015-08-25  Brian Burg  <bburg@apple.com>
+
+        Web Inspector: no need to allocate protocolErrors array for every dispatched backend command
+        https://bugs.webkit.org/show_bug.cgi?id=146466
+
+        Reviewed by Joseph Pecoraro.
+
+        * inspector/protocol/backend-dispatcher-argument-errors-expected.txt:
+        * inspector/protocol/backend-dispatcher-argument-errors.html:
+        Stringify the 'data' member before dumping, since it now contains JSON. Rebaseline it.
+
 2015-08-26  Enrica Casucci  <enrica@apple.com>
 
         Add some new emoji with modifiers and new sequence.
index 44c4942..7510371 100644 (file)
@@ -8,7 +8,7 @@ PASS: the backend should send a protocol error when receiving an invalid message
 PASS: the reported error should be "InvalidParams" (-32602)
 Actual error code: -32602
 Actual error message: Some arguments of method 'Runtime.evaluate' can't be processed
-Actual error data: 'params' object must contain required parameter 'expression' with type 'String'.
+Actual error data: [{"code":-32602,"message":"'params' object must contain required parameter 'expression' with type 'String'."},{"code":-32602,"message":"Some arguments of method 'Runtime.evaluate' can't be processed"}]
 
 -- Running test case: MissingRequiredParameter
 Sending message: {"id":123,"method":"Runtime.evaluate","params":{"stuff":123}}
@@ -16,7 +16,7 @@ PASS: the backend should send a protocol error when receiving an invalid message
 PASS: the reported error should be "InvalidParams" (-32602)
 Actual error code: -32602
 Actual error message: Some arguments of method 'Runtime.evaluate' can't be processed
-Actual error data: Parameter 'expression' with type 'String' was not found.
+Actual error data: [{"code":-32602,"message":"Parameter 'expression' with type 'String' was not found."},{"code":-32602,"message":"Some arguments of method 'Runtime.evaluate' can't be processed"}]
 
 -- Running test case: RequiredParameterWrongType
 Sending message: {"id":123,"method":"Runtime.evaluate","params":{"expression":[]}}
@@ -24,7 +24,7 @@ PASS: the backend should send a protocol error when receiving an invalid message
 PASS: the reported error should be "InvalidParams" (-32602)
 Actual error code: -32602
 Actual error message: Some arguments of method 'Runtime.evaluate' can't be processed
-Actual error data: Parameter 'expression' has wrong type. It must be 'String'.
+Actual error data: [{"code":-32602,"message":"Parameter 'expression' has wrong type. It must be 'String'."},{"code":-32602,"message":"Some arguments of method 'Runtime.evaluate' can't be processed"}]
 
 -- Running test case: OptionalParameterWrongType
 Sending message: {"id":123,"method":"Runtime.evaluate","params":{"expression":"42","includeCommandLineAPI":123}}
@@ -32,7 +32,7 @@ PASS: the backend should send a protocol error when receiving an invalid message
 PASS: the reported error should be "InvalidParams" (-32602)
 Actual error code: -32602
 Actual error message: Some arguments of method 'Runtime.evaluate' can't be processed
-Actual error data: Parameter 'includeCommandLineAPI' has wrong type. It must be 'Boolean'.
+Actual error data: [{"code":-32602,"message":"Parameter 'includeCommandLineAPI' has wrong type. It must be 'Boolean'."},{"code":-32602,"message":"Some arguments of method 'Runtime.evaluate' can't be processed"}]
 
 -- Running test case: TestErrorCodeForSyncServerError
 Sending message: {"id":123,"method":"Database.getDatabaseTableNames","params":{"databaseId":"thisisNotADatabase"}}
@@ -40,6 +40,7 @@ PASS: the backend should send a protocol error when receiving an invalid message
 PASS: the reported error should be "ServerError" (-32000)
 Actual error code: -32000
 Actual error message: Database agent is not enabled
+Actual error data: [{"code":-32000,"message":"Database agent is not enabled"}]
 
 -- Running test case: TestErrorCodeForAsyncServerError
 Sending message: {"id":123,"method":"Database.executeSQL","params":{"databaseId":"thisisNotADatabase","query":"asdf"}}
@@ -47,6 +48,7 @@ PASS: the backend should send a protocol error when receiving an invalid message
 PASS: the reported error should be "ServerError" (-32000)
 Actual error code: -32000
 Actual error message: Database agent is not enabled
+Actual error data: [{"code":-32000,"message":"Database agent is not enabled"}]
 
 -- Running test case: CommandWithBadArgumentValue
 Sending message: {"id":123,"method":"Runtime.getProperties","params":{"objectId":"thisisNotAnId"}}
@@ -54,4 +56,5 @@ PASS: the backend should send a protocol error when receiving an invalid message
 PASS: the reported error should be "ServerError" (-32000)
 Actual error code: -32000
 Actual error message: Inspected frame has gone
+Actual error data: [{"code":-32000,"message":"Inspected frame has gone"}]
 
index 150e832..05aa7e4 100644 (file)
@@ -36,7 +36,7 @@ function test()
                     ProtocolTest.log("Actual error code: " + response.code);
                     ProtocolTest.log("Actual error message: " + response.message);
                     if (response.data)
-                        ProtocolTest.log("Actual error data: " + response.data);
+                        ProtocolTest.log("Actual error data: " + JSON.stringify(response.data));
 
                     resolve();
                 })
index 729992e..a4ced7b 100644 (file)
@@ -1,3 +1,95 @@
+2015-08-25  Brian Burg  <bburg@apple.com>
+
+        Web Inspector: no need to allocate protocolErrors array for every dispatched backend command
+        https://bugs.webkit.org/show_bug.cgi?id=146466
+
+        Reviewed by Joseph Pecoraro.
+
+        Clean up some of the backend dispatcher code, with a focus on eliminating useless allocations
+        of objects in the common case when no protocol errors happen. This is done by saving the
+        current id of each request as it is being processed by the backend dispatcher, and tagging any
+        subsequent errors with that id. This also means we don't have to thread the requestId except
+        in the async command code path.
+
+        This patch also lifts some common code shared between all generated backend command
+        implementatations into the per-domain dispatch method instead. This reduces generated code size.
+
+        To be consistent, this patch standardizes on calling the id of a backend message its 'requestId'.
+        Requests can be handled synchronously or asynchronously (triggered via the 'async' property).
+
+        No new tests, covered by existing protocol tests.
+
+        * inspector/InspectorBackendDispatcher.cpp:
+        (Inspector::BackendDispatcher::CallbackBase::CallbackBase): Split the two code paths for reporting
+        success and failure.
+
+        (Inspector::BackendDispatcher::CallbackBase::sendFailure):
+        (Inspector::BackendDispatcher::CallbackBase::sendSuccess): Renamed from sendIfActive.
+        (Inspector::BackendDispatcher::dispatch): Reset counters and current requestId before dispatching.
+        No need to manually thread the requestId to all reportProtocolError calls.
+
+        (Inspector::BackendDispatcher::hasProtocolErrors): Added.
+        (Inspector::BackendDispatcher::sendResponse):
+        (Inspector::BackendDispatcher::sendPendingErrors): Send any saved protocol errors to the frontend.
+        Always send a 'data' member with all of the errors, even if there's just one. We might want to add
+        more information about errors later.
+
+        (Inspector::BackendDispatcher::reportProtocolError): Enqueue a protocol error to be sent later.
+        (Inspector::BackendDispatcher::getPropertyValue): Remove useless type parameters and nuke most of
+        the type conversion methods. Use std::function types instead of function pointer types.
+
+        (Inspector::castToInteger): Added.
+        (Inspector::castToNumber): Added.
+        (Inspector::BackendDispatcher::getInteger):
+        (Inspector::BackendDispatcher::getDouble):
+        (Inspector::BackendDispatcher::getString):
+        (Inspector::BackendDispatcher::getBoolean):
+        (Inspector::BackendDispatcher::getObject):
+        (Inspector::BackendDispatcher::getArray):
+        (Inspector::BackendDispatcher::getValue):
+        (Inspector::getPropertyValue): Deleted.
+        (Inspector::AsMethodBridges::asInteger): Deleted.
+        (Inspector::AsMethodBridges::asDouble): Deleted.
+        (Inspector::AsMethodBridges::asString): Deleted.
+        (Inspector::AsMethodBridges::asBoolean): Deleted.
+        (Inspector::AsMethodBridges::asObject): Deleted.
+        (Inspector::AsMethodBridges::asArray): Deleted.
+        (Inspector::AsMethodBridges::asValue): Deleted.
+        * inspector/InspectorBackendDispatcher.h:
+        * inspector/scripts/codegen/cpp_generator_templates.py: Extract 'params' object in domain dispatch method.
+        Omit requestIds where possible. Convert dispatch tables to use NeverDestroyed. Check the protocol error count
+        to decide whether to abort the dispatch or not, rather than allocating our own errors array.
+
+        * inspector/scripts/codegen/cpp_generator_templates.py:
+        (void):
+        * inspector/scripts/codegen/generate_cpp_backend_dispatcher_header.py: Revert to passing RefPtr<InspectorObject>
+        since parameters are now being passed rather than the message object. Some commands do not require parameters.
+        * inspector/scripts/codegen/generate_cpp_backend_dispatcher_implementation.py:
+        (CppBackendDispatcherImplementationGenerator.generate_output):
+        (CppBackendDispatcherImplementationGenerator._generate_small_dispatcher_switch_implementation_for_domain):
+        (CppBackendDispatcherImplementationGenerator._generate_dispatcher_implementation_for_command):
+        * inspector/scripts/codegen/generate_objc_backend_dispatcher_header.py:
+        (ObjCBackendDispatcherHeaderGenerator._generate_objc_handler_declaration_for_command):
+        * inspector/scripts/codegen/generate_objc_backend_dispatcher_implementation.py:
+        (ObjCConfigurationImplementationGenerator._generate_handler_implementation_for_command):
+        (ObjCConfigurationImplementationGenerator._generate_success_block_for_command):
+        * inspector/scripts/codegen/objc_generator_templates.py:
+
+        Rebaseline some protocol generator tests.
+        * inspector/scripts/tests/expected/commands-with-async-attribute.json-result:
+        * inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result:
+        * inspector/scripts/tests/expected/domains-with-varying-command-sizes.json-result:
+        * inspector/scripts/tests/expected/enum-values.json-result:
+        * inspector/scripts/tests/expected/events-with-optional-parameters.json-result:
+        * inspector/scripts/tests/expected/generate-domains-with-feature-guards.json-result:
+        * inspector/scripts/tests/expected/same-type-id-different-domain.json-result:
+        * inspector/scripts/tests/expected/shadowed-optional-type-setters.json-result:
+        * inspector/scripts/tests/expected/type-declaration-aliased-primitive-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-array-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-enum-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-object-type.json-result:
+        * inspector/scripts/tests/expected/type-requiring-runtime-casts.json-result:
+
 2015-08-25  Saam barati  <sbarati@apple.com>
 
         Lets rename codeOriginIndex to callSiteIndex and get rid of CallFrame::Location.
index d67ab99..371c0a9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All Rights Reserved.
  * Copyright (C) 2011 The Chromium Authors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 
 #include "InspectorFrontendChannel.h"
 #include "InspectorValues.h"
+#include <wtf/TemporaryChange.h>
 #include <wtf/text/CString.h>
 #include <wtf/text/WTFString.h>
 
 namespace Inspector {
 
-BackendDispatcher::CallbackBase::CallbackBase(Ref<BackendDispatcher>&& backendDispatcher, int id)
+BackendDispatcher::CallbackBase::CallbackBase(Ref<BackendDispatcher>&& backendDispatcher, long requestId)
     : m_backendDispatcher(WTF::move(backendDispatcher))
-    , m_id(id)
-    , m_alreadySent(false)
+    , m_requestId(requestId)
 {
 }
 
@@ -49,16 +49,24 @@ bool BackendDispatcher::CallbackBase::isActive() const
 void BackendDispatcher::CallbackBase::sendFailure(const ErrorString& error)
 {
     ASSERT(error.length());
-    sendIfActive(nullptr, error);
+
+    if (m_alreadySent)
+        return;
+
+    m_alreadySent = true;
+
+    // Immediately send an error message since this is an async response with a single error.
+    m_backendDispatcher->reportProtocolError(m_requestId, ServerError, error);
+    m_backendDispatcher->sendPendingErrors();
 }
 
-void BackendDispatcher::CallbackBase::sendIfActive(RefPtr<InspectorObject>&& partialMessage, const ErrorString& invocationError)
+void BackendDispatcher::CallbackBase::sendSuccess(RefPtr<InspectorObject>&& partialMessage)
 {
     if (m_alreadySent)
         return;
 
-    m_backendDispatcher->sendResponse(m_id, WTF::move(partialMessage), invocationError);
     m_alreadySent = true;
+    m_backendDispatcher->sendResponse(m_requestId, WTF::move(partialMessage));
 }
 
 Ref<BackendDispatcher> BackendDispatcher::create(FrontendChannel* frontendChannel)
@@ -76,83 +84,94 @@ void BackendDispatcher::dispatch(const String& message)
 {
     Ref<BackendDispatcher> protect(*this);
 
+    ASSERT(!m_protocolErrors.size());
+
     RefPtr<InspectorValue> parsedMessage;
     if (!InspectorValue::parseJSON(message, parsedMessage)) {
-        reportProtocolError(nullptr, ParseError, ASCIILiteral("Message must be in JSON format"));
+        reportProtocolError(ParseError, ASCIILiteral("Message must be in JSON format"));
+        sendPendingErrors();
         return;
     }
 
     RefPtr<InspectorObject> messageObject;
     if (!parsedMessage->asObject(messageObject)) {
-        reportProtocolError(nullptr, InvalidRequest, ASCIILiteral("Message must be a JSONified object"));
+        reportProtocolError(InvalidRequest, ASCIILiteral("Message must be a JSONified object"));
+        sendPendingErrors();
         return;
     }
 
-    RefPtr<InspectorValue> callIdValue;
-    if (!messageObject->getValue(ASCIILiteral("id"), callIdValue)) {
-        reportProtocolError(nullptr, InvalidRequest, ASCIILiteral("'id' property was not found"));
+    RefPtr<InspectorValue> requestIdValue;
+    if (!messageObject->getValue(ASCIILiteral("id"), requestIdValue)) {
+        reportProtocolError(InvalidRequest, ASCIILiteral("'id' property was not found"));
+        sendPendingErrors();
         return;
     }
 
-    long callId = 0;
-    if (!callIdValue->asInteger(callId)) {
-        reportProtocolError(nullptr, InvalidRequest, ASCIILiteral("The type of 'id' property must be integer"));
+    long requestId = 0;
+    if (!requestIdValue->asInteger(requestId)) {
+        reportProtocolError(InvalidRequest, ASCIILiteral("The type of 'id' property must be integer"));
+        sendPendingErrors();
         return;
     }
 
+    ASSERT(!m_currentRequestId);
+    TemporaryChange<Optional<long>> scopedRequestId(m_currentRequestId, requestId);
+
     RefPtr<InspectorValue> methodValue;
     if (!messageObject->getValue(ASCIILiteral("method"), methodValue)) {
-        reportProtocolError(&callId, InvalidRequest, ASCIILiteral("'method' property wasn't found"));
+        reportProtocolError(InvalidRequest, ASCIILiteral("'method' property wasn't found"));
+        sendPendingErrors();
         return;
     }
 
     String methodString;
     if (!methodValue->asString(methodString)) {
-        reportProtocolError(&callId, InvalidRequest, ASCIILiteral("The type of 'method' property must be string"));
+        reportProtocolError(InvalidRequest, ASCIILiteral("The type of 'method' property must be string"));
+        sendPendingErrors();
         return;
     }
 
     Vector<String> domainAndMethod;
     methodString.split('.', true, domainAndMethod);
     if (domainAndMethod.size() != 2 || !domainAndMethod[0].length() || !domainAndMethod[1].length()) {
-        reportProtocolError(&callId, InvalidRequest, ASCIILiteral("The 'method' property was formatted incorrectly. It should be 'Domain.method'"));
+        reportProtocolError(InvalidRequest, ASCIILiteral("The 'method' property was formatted incorrectly. It should be 'Domain.method'"));
+        sendPendingErrors();
         return;
     }
 
     String domain = domainAndMethod[0];
     SupplementalBackendDispatcher* domainDispatcher = m_dispatchers.get(domain);
     if (!domainDispatcher) {
-        reportProtocolError(&callId, MethodNotFound, "'" + domain + "' domain was not found");
+        reportProtocolError(MethodNotFound, "'" + domain + "' domain was not found");
+        sendPendingErrors();
         return;
     }
 
     String method = domainAndMethod[1];
-    domainDispatcher->dispatch(callId, method, messageObject.releaseNonNull());
+    domainDispatcher->dispatch(requestId, method, messageObject.releaseNonNull());
+
+    if (m_protocolErrors.size())
+        sendPendingErrors();
 }
 
-void BackendDispatcher::sendResponse(long callId, RefPtr<InspectorObject>&& result, const ErrorString& invocationError)
+void BackendDispatcher::sendResponse(long requestId, RefPtr<InspectorObject>&& result)
 {
     if (!m_frontendChannel)
         return;
 
-    if (invocationError.length()) {
-        reportProtocolError(&callId, ServerError, invocationError);
-        return;
-    }
+    ASSERT(!m_protocolErrors.size());
 
+    // The JSON-RPC 2.0 specification requires that the "error" member have the value 'null'
+    // if no error occurred during an invocation, but we do not include it at all.
     Ref<InspectorObject> responseMessage = InspectorObject::create();
     responseMessage->setObject(ASCIILiteral("result"), result);
-    responseMessage->setInteger(ASCIILiteral("id"), callId);
+    responseMessage->setInteger(ASCIILiteral("id"), requestId);
     m_frontendChannel->sendMessageToFrontend(responseMessage->toJSONString());
 }
 
-void BackendDispatcher::reportProtocolError(const long* const callId, CommonErrorCode errorCode, const String& errorMessage) const
-{
-    reportProtocolError(callId, errorCode, errorMessage, nullptr);
-}
-
-void BackendDispatcher::reportProtocolError(const long* const callId, CommonErrorCode errorCode, const String& errorMessage, RefPtr<Inspector::Protocol::Array<String>>&& data) const
+void BackendDispatcher::sendPendingErrors()
 {
+    // These error codes are specified in JSON-RPC 2.0, Section 5.1.
     static const int errorCodes[] = {
         -32700, // ParseError
         -32600, // InvalidRequest
@@ -162,33 +181,69 @@ void BackendDispatcher::reportProtocolError(const long* const callId, CommonErro
         -32000, // ServerError
     };
 
-    ASSERT_ARG(errorCode, errorCode >= 0);
-    ASSERT_ARG(errorCode, (unsigned)errorCode < WTF_ARRAY_LENGTH(errorCodes));
-    ASSERT_ARG(errorCode, errorCodes[errorCode]);
-
     if (!m_frontendChannel)
         return;
+    
+    // To construct the error object, only use the last error's code and message.
+    // Per JSON-RPC 2.0, Section 5.1, the 'data' member may contain nested errors,
+    // but only one top-level Error object should be sent per request.
+    CommonErrorCode errorCode;
+    String errorMessage;
+    Ref<InspectorArray> payload = InspectorArray::create();
+    
+    for (auto& data : m_protocolErrors) {
+        errorCode = std::get<0>(data);
+        errorMessage = std::get<1>(data);
+
+        ASSERT_ARG(errorCode, (unsigned)errorCode < WTF_ARRAY_LENGTH(errorCodes));
+        ASSERT_ARG(errorCode, errorCodes[errorCode]);
+
+        Ref<InspectorObject> error = InspectorObject::create();
+        error->setInteger(ASCIILiteral("code"), errorCodes[errorCode]);
+        error->setString(ASCIILiteral("message"), errorMessage);
+        payload->pushObject(WTF::move(error));
+    }
 
-    Ref<InspectorObject> error = InspectorObject::create();
-    error->setInteger(ASCIILiteral("code"), errorCodes[errorCode]);
-    error->setString(ASCIILiteral("message"), errorMessage);
-    if (data)
-        error->setArray(ASCIILiteral("data"), WTF::move(data));
+    Ref<InspectorObject> topLevelError = InspectorObject::create();
+    topLevelError->setInteger(ASCIILiteral("code"), errorCodes[errorCode]);
+    topLevelError->setString(ASCIILiteral("message"), errorMessage);
+    topLevelError->setArray(ASCIILiteral("data"), WTF::move(payload));
 
     Ref<InspectorObject> message = InspectorObject::create();
-    message->setObject(ASCIILiteral("error"), WTF::move(error));
-    if (callId)
-        message->setInteger(ASCIILiteral("id"), *callId);
-    else
+    message->setObject(ASCIILiteral("error"), WTF::move(topLevelError));
+    if (m_currentRequestId)
+        message->setInteger(ASCIILiteral("id"), m_currentRequestId.value());
+    else {
+        // The 'null' value for an unknown id is specified in JSON-RPC 2.0, Section 5.
         message->setValue(ASCIILiteral("id"), InspectorValue::null());
+    }
 
     m_frontendChannel->sendMessageToFrontend(message->toJSONString());
+
+    m_protocolErrors.clear();
+    m_currentRequestId = Nullopt;
+}
+    
+void BackendDispatcher::reportProtocolError(CommonErrorCode errorCode, const String& errorMessage)
+{
+    reportProtocolError(m_currentRequestId, errorCode, errorMessage);
 }
 
-template<typename ReturnValueType, typename ValueType, typename DefaultValueType>
-static ReturnValueType getPropertyValue(InspectorObject* object, const String& name, bool* out_optionalValueFound, Inspector::Protocol::Array<String>& protocolErrors, DefaultValueType defaultValue, bool (*asMethod)(InspectorValue&, ValueType&), const char* typeName)
+void BackendDispatcher::reportProtocolError(Optional<long> relatedRequestId, CommonErrorCode errorCode, const String& errorMessage)
 {
-    ValueType result = defaultValue;
+    ASSERT_ARG(errorCode, errorCode >= 0);
+
+    // If the error was reported from an async callback, then no request id will be registered yet.
+    if (!m_currentRequestId)
+        m_currentRequestId = relatedRequestId;
+
+    m_protocolErrors.append(std::tuple<CommonErrorCode, String>(errorCode, errorMessage));
+}
+
+template<typename T>
+T BackendDispatcher::getPropertyValue(InspectorObject* object, const String& name, bool* out_optionalValueFound, T defaultValue, std::function<bool(InspectorValue&, T&)> asMethod, const char* typeName)
+{
+    T result(defaultValue);
     // out_optionalValueFound signals to the caller whether an optional property was found.
     // if out_optionalValueFound == nullptr, then this is a required property.
     if (out_optionalValueFound)
@@ -196,19 +251,19 @@ static ReturnValueType getPropertyValue(InspectorObject* object, const String& n
 
     if (!object) {
         if (!out_optionalValueFound)
-            protocolErrors.addItem(String::format("'params' object must contain required parameter '%s' with type '%s'.", name.utf8().data(), typeName));
+            reportProtocolError(BackendDispatcher::InvalidParams, String::format("'params' object must contain required parameter '%s' with type '%s'.", name.utf8().data(), typeName));
         return result;
     }
 
     auto findResult = object->find(name);
     if (findResult == object->end()) {
         if (!out_optionalValueFound)
-            protocolErrors.addItem(String::format("Parameter '%s' with type '%s' was not found.", name.utf8().data(), typeName));
+            reportProtocolError(BackendDispatcher::InvalidParams, String::format("Parameter '%s' with type '%s' was not found.", name.utf8().data(), typeName));
         return result;
     }
 
     if (!asMethod(*findResult->value, result)) {
-        protocolErrors.addItem(String::format("Parameter '%s' has wrong type. It must be '%s'.", name.utf8().data(), typeName));
+        reportProtocolError(BackendDispatcher::InvalidParams, String::format("Parameter '%s' has wrong type. It must be '%s'.", name.utf8().data(), typeName));
         return result;
     }
 
@@ -218,49 +273,42 @@ static ReturnValueType getPropertyValue(InspectorObject* object, const String& n
     return result;
 }
 
-struct AsMethodBridges {
-    static bool asInteger(InspectorValue& value, int& output) { return value.asInteger(output); }
-    static bool asDouble(InspectorValue& value, double& output) { return value.asDouble(output); }
-    static bool asString(InspectorValue& value, String& output) { return value.asString(output); }
-    static bool asBoolean(InspectorValue& value, bool& output) { return value.asBoolean(output); }
-    static bool asObject(InspectorValue& value, RefPtr<InspectorObject>& output) { return value.asObject(output); }
-    static bool asArray(InspectorValue& value, RefPtr<InspectorArray>& output) { return value.asArray(output); }
-    static bool asValue(InspectorValue& value, RefPtr<InspectorValue>& output) { return value.asValue(output); }
-};
-
-int BackendDispatcher::getInteger(InspectorObject* object, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors)
+static bool castToInteger(InspectorValue& value, int& result) { return value.asInteger(result); }
+static bool castToNumber(InspectorValue& value, double& result) { return value.asDouble(result); }
+
+int BackendDispatcher::getInteger(InspectorObject* object, const String& name, bool* valueFound)
 {
-    return getPropertyValue<int, int, int>(object, name, valueFound, protocolErrors, 0, AsMethodBridges::asInteger, "Integer");
+    return getPropertyValue<int>(object, name, valueFound, 0, &castToInteger, "Integer");
 }
 
-double BackendDispatcher::getDouble(InspectorObject* object, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors)
+double BackendDispatcher::getDouble(InspectorObject* object, const String& name, bool* valueFound)
 {
-    return getPropertyValue<double, double, double>(object, name, valueFound, protocolErrors, 0, AsMethodBridges::asDouble, "Number");
+    return getPropertyValue<double>(object, name, valueFound, 0, &castToNumber, "Number");
 }
 
-String BackendDispatcher::getString(InspectorObject* object, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors)
+String BackendDispatcher::getString(InspectorObject* object, const String& name, bool* valueFound)
 {
-    return getPropertyValue<String, String, String>(object, name, valueFound, protocolErrors, "", AsMethodBridges::asString, "String");
+    return getPropertyValue<String>(object, name, valueFound, "", &InspectorValue::asString, "String");
 }
 
-bool BackendDispatcher::getBoolean(InspectorObject* object, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors)
+bool BackendDispatcher::getBoolean(InspectorObject* object, const String& name, bool* valueFound)
 {
-    return getPropertyValue<bool, bool, bool>(object, name, valueFound, protocolErrors, false, AsMethodBridges::asBoolean, "Boolean");
+    return getPropertyValue<bool>(object, name, valueFound, false, &InspectorValue::asBoolean, "Boolean");
 }
 
-RefPtr<InspectorObject> BackendDispatcher::getObject(InspectorObject* object, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors)
+RefPtr<InspectorObject> BackendDispatcher::getObject(InspectorObject* object, const String& name, bool* valueFound)
 {
-    return getPropertyValue<RefPtr<InspectorObject>, RefPtr<InspectorObject>, InspectorObject*>(object, name, valueFound, protocolErrors, nullptr, AsMethodBridges::asObject, "Object");
+    return getPropertyValue<RefPtr<InspectorObject>>(object, name, valueFound, nullptr, &InspectorValue::asObject, "Object");
 }
 
-RefPtr<InspectorArray> BackendDispatcher::getArray(InspectorObject* object, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors)
+RefPtr<InspectorArray> BackendDispatcher::getArray(InspectorObject* object, const String& name, bool* valueFound)
 {
-    return getPropertyValue<RefPtr<InspectorArray>, RefPtr<InspectorArray>, InspectorArray*>(object, name, valueFound, protocolErrors, nullptr, AsMethodBridges::asArray, "Array");
+    return getPropertyValue<RefPtr<InspectorArray>>(object, name, valueFound, nullptr, &InspectorValue::asArray, "Array");
 }
 
-RefPtr<InspectorValue> BackendDispatcher::getValue(InspectorObject* object, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors)
+RefPtr<InspectorValue> BackendDispatcher::getValue(InspectorObject* object, const String& name, bool* valueFound)
 {
-    return getPropertyValue<RefPtr<InspectorValue>, RefPtr<InspectorValue>, InspectorValue*>(object, name, valueFound, protocolErrors, nullptr, AsMethodBridges::asValue, "Value");
+    return getPropertyValue<RefPtr<InspectorValue>>(object, name, valueFound, nullptr, &InspectorValue::asValue, "Value");
 }
 
 } // namespace Inspector
index b303700..f22482d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All Rights Reserved.
  * Copyright (C) 2011 The Chromium Authors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -28,6 +28,7 @@
 #define InspectorBackendDispatcher_h
 
 #include "InspectorProtocolTypes.h"
+#include <wtf/Optional.h>
 #include <wtf/RefCounted.h>
 #include <wtf/text/WTFString.h>
 
@@ -43,35 +44,36 @@ public:
     SupplementalBackendDispatcher(BackendDispatcher& backendDispatcher)
         : m_backendDispatcher(backendDispatcher) { }
     virtual ~SupplementalBackendDispatcher() { }
-    virtual void dispatch(long callId, const String& method, Ref<InspectorObject>&& message) = 0;
+    virtual void dispatch(long requestId, const String& method, Ref<InspectorObject>&& message) = 0;
 protected:
     Ref<BackendDispatcher> m_backendDispatcher;
 };
 
-class JS_EXPORT_PRIVATE BackendDispatcher : public RefCounted<BackendDispatcher> {
+class BackendDispatcher : public RefCounted<BackendDispatcher> {
 public:
-    static Ref<BackendDispatcher> create(FrontendChannel*);
+    JS_EXPORT_PRIVATE static Ref<BackendDispatcher> create(FrontendChannel*);
 
     class JS_EXPORT_PRIVATE CallbackBase : public RefCounted<CallbackBase> {
     public:
-        CallbackBase(Ref<BackendDispatcher>&&, int id);
+        CallbackBase(Ref<BackendDispatcher>&&, long requestId);
 
         bool isActive() const;
-        void sendFailure(const ErrorString&);
         void disable() { m_alreadySent = true; }
 
-    protected:
-        void sendIfActive(RefPtr<InspectorObject>&& partialMessage, const ErrorString& invocationError);
+        void sendSuccess(RefPtr<InspectorObject>&&);
+        void sendFailure(const ErrorString&);
 
     private:
         Ref<BackendDispatcher> m_backendDispatcher;
-        int m_id;
-        bool m_alreadySent;
+        long m_requestId;
+        bool m_alreadySent { false };
     };
 
     void clearFrontend() { m_frontendChannel = nullptr; }
     bool isActive() const { return !!m_frontendChannel; }
 
+    bool hasProtocolErrors() const { return m_protocolErrors.size() > 0; }
+
     enum CommonErrorCode {
         ParseError = 0,
         InvalidRequest,
@@ -82,25 +84,42 @@ public:
     };
 
     void registerDispatcherForDomain(const String& domain, SupplementalBackendDispatcher*);
-    void dispatch(const String& message);
-    void sendResponse(long callId, RefPtr<InspectorObject>&& result, const ErrorString& invocationError);
-    void reportProtocolError(const long* const callId, CommonErrorCode, const String& errorMessage) const;
-    void reportProtocolError(const long* const callId, CommonErrorCode, const String& errorMessage, RefPtr<Inspector::Protocol::Array<String>>&& data) const;
-
-    static int getInteger(InspectorObject*, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors);
-    static double getDouble(InspectorObject*, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors);
-    static String getString(InspectorObject*, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors);
-    static bool getBoolean(InspectorObject*, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors);
-    static RefPtr<InspectorValue> getValue(InspectorObject*, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors);
-    static RefPtr<InspectorObject> getObject(InspectorObject*, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors);
-    static RefPtr<InspectorArray> getArray(InspectorObject*, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors);
+    JS_EXPORT_PRIVATE void dispatch(const String& message);
+
+    JS_EXPORT_PRIVATE void sendResponse(long requestId, RefPtr<InspectorObject>&& result);
+    JS_EXPORT_PRIVATE void sendPendingErrors();
+
+    void reportProtocolError(CommonErrorCode, const String& errorMessage);
+    JS_EXPORT_PRIVATE void reportProtocolError(Optional<long> relatedRequestId, CommonErrorCode, const String& errorMessage);
+
+    template<typename T>
+    T getPropertyValue(InspectorObject*, const String& name, bool* out_optionalValueFound, T defaultValue, std::function<bool(InspectorValue&, T&)>, const char* typeName);
+
+    int getInteger(InspectorObject*, const String& name, bool* valueFound);
+    double getDouble(InspectorObject*, const String& name, bool* valueFound);
+    String getString(InspectorObject*, const String& name, bool* valueFound);
+    bool getBoolean(InspectorObject*, const String& name, bool* valueFound);
+    RefPtr<InspectorValue> getValue(InspectorObject*, const String& name, bool* valueFound);
+    RefPtr<InspectorObject> getObject(InspectorObject*, const String& name, bool* valueFound);
+    RefPtr<InspectorArray> getArray(InspectorObject*, const String& name, bool* valueFound);
 
 private:
-    BackendDispatcher(FrontendChannel* FrontendChannel)
-        : m_frontendChannel(FrontendChannel) { }
+    BackendDispatcher(FrontendChannel* channel)
+        : m_frontendChannel(channel)
+    {
+    }
 
     FrontendChannel* m_frontendChannel;
     HashMap<String, SupplementalBackendDispatcher*> m_dispatchers;
+
+    // Protocol errors reported for the top-level request being processed.
+    // If processing a request triggers async responses, then any related errors will
+    // be attributed to the top-level request, but generate separate error messages.
+    Vector<std::tuple<CommonErrorCode, String>> m_protocolErrors;
+
+    // For synchronously handled requests, avoid plumbing requestId through every
+    // call that could potentially fail with a protocol error.
+    Optional<long> m_currentRequestId { Nullopt };
 };
 
 } // namespace Inspector
index 05f3530..75071c6 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright (c) 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2014, 2015 Apple Inc. All rights reserved.
 # Copyright (c) 2014 University of Washington. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -101,7 +101,7 @@ protected:
     """${classAndExportMacro} ${domainName}BackendDispatcher final : public SupplementalBackendDispatcher {
 public:
     static Ref<${domainName}BackendDispatcher> create(BackendDispatcher*, ${domainName}BackendDispatcherHandler*);
-    virtual void dispatch(long callId, const String& method, Ref<InspectorObject>&& message) override;
+    virtual void dispatch(long requestId, const String& method, Ref<InspectorObject>&& message) override;
 ${commandDeclarations}
 private:
     ${domainName}BackendDispatcher(BackendDispatcher&, ${domainName}BackendDispatcherHandler*);
@@ -123,24 +123,30 @@ private:
     virtual void ${commandName}(${inParameters}) = 0;""")
 
     BackendDispatcherImplementationSmallSwitch = (
-    """void ${domainName}BackendDispatcher::dispatch(long callId, const String& method, Ref<InspectorObject>&& message)
+    """void ${domainName}BackendDispatcher::dispatch(long requestId, const String& method, Ref<InspectorObject>&& message)
 {
     Ref<${domainName}BackendDispatcher> protect(*this);
 
+    RefPtr<InspectorObject> parameters;
+    message->getObject(ASCIILiteral("params"), parameters);
+
 ${dispatchCases}
     else
-        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::MethodNotFound, makeString('\\'', "${domainName}", '.', method, "' was not found"));
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::MethodNotFound, makeString('\\'', "${domainName}", '.', method, "' was not found"));
 }""")
 
     BackendDispatcherImplementationLargeSwitch = (
-"""void ${domainName}BackendDispatcher::dispatch(long callId, const String& method, Ref<InspectorObject>&& message)
+"""void ${domainName}BackendDispatcher::dispatch(long requestId, const String& method, Ref<InspectorObject>&& message)
 {
     Ref<${domainName}BackendDispatcher> protect(*this);
 
-    typedef void (${domainName}BackendDispatcher::*CallHandler)(long callId, const InspectorObject& message);
+    RefPtr<InspectorObject> parameters;
+    message->getObject(ASCIILiteral("params"), parameters);
+
+    typedef void (${domainName}BackendDispatcher::*CallHandler)(long requestId, RefPtr<InspectorObject>&& message);
     typedef HashMap<String, CallHandler> DispatchMap;
-    DEPRECATED_DEFINE_STATIC_LOCAL(DispatchMap, dispatchMap, ());
-    if (dispatchMap.isEmpty()) {
+    static NeverDestroyed<DispatchMap> dispatchMap;
+    if (dispatchMap.get().isEmpty()) {
         static const struct MethodTable {
             const char* name;
             CallHandler handler;
@@ -149,16 +155,16 @@ ${dispatchCases}
         };
         size_t length = WTF_ARRAY_LENGTH(commands);
         for (size_t i = 0; i < length; ++i)
-            dispatchMap.add(commands[i].name, commands[i].handler);
+            dispatchMap.get().add(commands[i].name, commands[i].handler);
     }
 
-    HashMap<String, CallHandler>::iterator it = dispatchMap.find(method);
-    if (it == dispatchMap.end()) {
-        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::MethodNotFound, makeString('\\'', "${domainName}", '.', method, "' was not found"));
+    auto findResult = dispatchMap.get().find(method);
+    if (findResult == dispatchMap.get().end()) {
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::MethodNotFound, makeString('\\'', "${domainName}", '.', method, "' was not found"));
         return;
     }
 
-    ((*this).*it->value)(callId, message.get());
+    ((*this).*findResult->value)(requestId, WTF::move(parameters));
 }""")
 
     BackendDispatcherImplementationDomainConstructor = (
@@ -178,13 +184,9 @@ ${domainName}BackendDispatcher::${domainName}BackendDispatcher(BackendDispatcher
 }""")
 
     BackendDispatcherImplementationPrepareCommandArguments = (
-"""    auto protocolErrors = Inspector::Protocol::Array<String>::create();
-    RefPtr<InspectorObject> paramsContainer;
-    message.getObject(ASCIILiteral("params"), paramsContainer);
-${inParameterDeclarations}
-    if (protocolErrors->length()) {
-        String errorMessage = String::format("Some arguments of method \'%s\' can't be processed", "${domainName}.${commandName}");
-        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::InvalidParams, errorMessage, WTF::move(protocolErrors));
+"""${inParameterDeclarations}
+    if (m_backendDispatcher->hasProtocolErrors()) {
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method \'%s\' can't be processed", "${domainName}.${commandName}"));
         return;
     }
 """)
@@ -196,7 +198,7 @@ void ${domainName}BackendDispatcherHandler::${callbackName}::sendSuccess(${forma
 {
     Ref<InspectorObject> jsonMessage = InspectorObject::create();
 ${outParameterAssignments}
-    sendIfActive(WTF::move(jsonMessage), ErrorString());
+    CallbackBase::sendSuccess(WTF::move(jsonMessage));
 }""")
 
     FrontendDispatcherDomainDispatcherDeclaration = (
index 54bdb3e..2e5ff7a 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright (c) 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2014, 2015 Apple Inc. All rights reserved.
 # Copyright (c) 2014 University of Washington. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -205,4 +205,4 @@ class CppBackendDispatcherHeaderGenerator(Generator):
         return self.wrap_with_guard_for_domain(domain, Template(CppTemplates.BackendDispatcherHeaderDomainDispatcherDeclaration).substitute(None, **handler_args))
 
     def _generate_dispatcher_declaration_for_command(self, command):
-        return "    void %s(long callId, const InspectorObject& message);" % command.command_name
+        return "    void %s(long requestId, RefPtr<InspectorObject>&& parameters);" % command.command_name
index 350f085..1251149 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright (c) 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2014, 2015 Apple Inc. All rights reserved.
 # Copyright (c) 2014 University of Washington. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -51,6 +51,7 @@ class CppBackendDispatcherImplementationGenerator(Generator):
         secondary_headers = [
             '<inspector/InspectorFrontendChannel.h>',
             '<inspector/InspectorValues.h>',
+            '<wtf/NeverDestroyed.h>',
             '<wtf/text/CString.h>']
 
         secondary_includes = ['#include %s' % header for header in secondary_headers]
@@ -104,10 +105,10 @@ class CppBackendDispatcherImplementationGenerator(Generator):
     def _generate_small_dispatcher_switch_implementation_for_domain(self, domain):
         cases = []
         cases.append('    if (method == "%s")' % domain.commands[0].command_name)
-        cases.append('        %s(callId, message);' % domain.commands[0].command_name)
+        cases.append('        %s(requestId, WTF::move(parameters));' % domain.commands[0].command_name)
         for command in domain.commands[1:]:
             cases.append('    else if (method == "%s")' % command.command_name)
-            cases.append('        %s(callId, message);' % command.command_name)
+            cases.append('        %s(requestId, WTF::move(parameters));' % command.command_name)
 
         switch_args = {
             'domainName': domain.domain_name,
@@ -170,7 +171,7 @@ class CppBackendDispatcherImplementationGenerator(Generator):
         in_parameter_declarations = []
         out_parameter_declarations = []
         out_parameter_assignments = []
-        alternate_dispatcher_method_parameters = ['callId']
+        alternate_dispatcher_method_parameters = ['requestId']
         method_parameters = ['error']
 
         for parameter in command.call_parameters:
@@ -207,7 +208,7 @@ class CppBackendDispatcherImplementationGenerator(Generator):
                 'successOutParam': out_success_argument
             }
 
-            in_parameter_declarations.append('    %(parameterType)s %(parameterName)s = BackendDispatcher::%(keyedGetMethod)s(paramsContainer.get(), ASCIILiteral("%(parameterKey)s"), %(successOutParam)s, protocolErrors.get());' % param_args)
+            in_parameter_declarations.append('    %(parameterType)s %(parameterName)s = m_backendDispatcher->%(keyedGetMethod)s(parameters.get(), ASCIILiteral("%(parameterKey)s"), %(successOutParam)s);' % param_args)
 
             if parameter.is_optional:
                 optional_in_parameter_string = '%(parameterName)s_valueFound ? %(parameterExpression)s : nullptr' % param_args
@@ -224,7 +225,7 @@ class CppBackendDispatcherImplementationGenerator(Generator):
             }
 
             out_parameter_assignments.append('        callback->disable();')
-            out_parameter_assignments.append('        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::ServerError, error);')
+            out_parameter_assignments.append('        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, error);')
             out_parameter_assignments.append('        return;')
             method_parameters.append('callback.copyRef()')
 
@@ -267,9 +268,9 @@ class CppBackendDispatcherImplementationGenerator(Generator):
 
         lines = []
         if len(command.call_parameters) == 0:
-            lines.append('void %(domainName)sBackendDispatcher::%(commandName)s(long callId, const InspectorObject&)' % command_args)
+            lines.append('void %(domainName)sBackendDispatcher::%(commandName)s(long requestId, RefPtr<InspectorObject>&&)' % command_args)
         else:
-            lines.append('void %(domainName)sBackendDispatcher::%(commandName)s(long callId, const InspectorObject& message)' % command_args)
+            lines.append('void %(domainName)sBackendDispatcher::%(commandName)s(long requestId, RefPtr<InspectorObject>&& parameters)' % command_args)
         lines.append('{')
 
         if len(command.call_parameters) > 0:
@@ -286,7 +287,7 @@ class CppBackendDispatcherImplementationGenerator(Generator):
         lines.append('    ErrorString error;')
         lines.append('    Ref<InspectorObject> result = InspectorObject::create();')
         if command.is_async:
-            lines.append('    Ref<%(domainName)sBackendDispatcherHandler::%(callbackName)s> callback = adoptRef(*new %(domainName)sBackendDispatcherHandler::%(callbackName)s(m_backendDispatcher.copyRef(), callId));' % command_args)
+            lines.append('    Ref<%(domainName)sBackendDispatcherHandler::%(callbackName)s> callback = adoptRef(*new %(domainName)sBackendDispatcherHandler::%(callbackName)s(m_backendDispatcher.copyRef(), requestId));' % command_args)
         if len(command.return_parameters) > 0:
             lines.extend(out_parameter_declarations)
         lines.append('    m_agent->%(commandName)s(%(invocationParameters)s);' % command_args)
@@ -305,6 +306,9 @@ class CppBackendDispatcherImplementationGenerator(Generator):
             lines.append('')
 
         if not command.is_async:
-            lines.append('    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);')
+            lines.append('    if (!error.length())')
+            lines.append('        m_backendDispatcher->sendResponse(requestId, WTF::move(result));')
+            lines.append('    else')
+            lines.append('        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTF::move(error));')
         lines.append('}')
         return "\n".join(lines)
index 29b38e8..d56a0b1 100755 (executable)
@@ -94,7 +94,7 @@ class ObjCBackendDispatcherHeaderGenerator(Generator):
 
     def _generate_objc_handler_declaration_for_command(self, command):
         lines = []
-        parameters = ['long callId']
+        parameters = ['long requestId']
         for _parameter in command.call_parameters:
             parameters.append('%s in_%s' % (CppGenerator.cpp_type_for_unchecked_formal_in_parameter(_parameter), _parameter.parameter_name))
 
index 27bdd4a..a277d78 100755 (executable)
@@ -82,7 +82,7 @@ class ObjCConfigurationImplementationGenerator(Generator):
 
     def _generate_handler_implementation_for_command(self, domain, command):
         lines = []
-        parameters = ['long callId']
+        parameters = ['long requestId']
         for parameter in command.call_parameters:
             parameters.append('%s in_%s' % (CppGenerator.cpp_type_for_unchecked_formal_in_parameter(parameter), parameter.parameter_name))
 
@@ -139,9 +139,9 @@ class ObjCConfigurationImplementationGenerator(Generator):
                 else:
                     lines.append('        if (%s)' % var_name)
                     lines.append('            resultObject->%s(ASCIILiteral("%s"), %s);' % (keyed_set_method, parameter.parameter_name, export_expression))
-            lines.append('        backendDispatcher()->sendResponse(callId, WTF::move(resultObject), String());')
+            lines.append('        backendDispatcher()->sendResponse(requestId, WTF::move(resultObject));')
         else:
-            lines.append('        backendDispatcher()->sendResponse(callId, InspectorObject::create(), String());')
+            lines.append('        backendDispatcher()->sendResponse(requestId, InspectorObject::create());')
 
         lines.append('    };')
         return '\n'.join(lines)
index ef712b8..a28a9ef 100755 (executable)
@@ -112,7 +112,8 @@ private:
     """void ObjCInspector${domainName}BackendDispatcher::${commandName}(${parameters})
 {
     id errorCallback = ^(NSString *error) {
-        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
+        backendDispatcher()->sendPendingErrors();
     };
 
 ${successCallback}
index 15d6a4d..e37f9c5 100644 (file)
@@ -187,12 +187,12 @@ protected:
 class DatabaseBackendDispatcher final : public SupplementalBackendDispatcher {
 public:
     static Ref<DatabaseBackendDispatcher> create(BackendDispatcher*, DatabaseBackendDispatcherHandler*);
-    virtual void dispatch(long callId, const String& method, Ref<InspectorObject>&& message) override;
+    virtual void dispatch(long requestId, const String& method, Ref<InspectorObject>&& message) override;
 private:
-    void executeSQLSyncOptionalReturnValues(long callId, const InspectorObject& message);
-    void executeSQLAsyncOptionalReturnValues(long callId, const InspectorObject& message);
-    void executeSQLSync(long callId, const InspectorObject& message);
-    void executeSQLAsync(long callId, const InspectorObject& message);
+    void executeSQLSyncOptionalReturnValues(long requestId, RefPtr<InspectorObject>&& parameters);
+    void executeSQLAsyncOptionalReturnValues(long requestId, RefPtr<InspectorObject>&& parameters);
+    void executeSQLSync(long requestId, RefPtr<InspectorObject>&& parameters);
+    void executeSQLAsync(long requestId, RefPtr<InspectorObject>&& parameters);
 private:
     DatabaseBackendDispatcher(BackendDispatcher&, DatabaseBackendDispatcherHandler*);
     DatabaseBackendDispatcherHandler* m_agent;
@@ -245,6 +245,7 @@ private:
 
 #include <inspector/InspectorFrontendChannel.h>
 #include <inspector/InspectorValues.h>
+#include <wtf/NeverDestroyed.h>
 #include <wtf/text/CString.h>
 
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
@@ -270,38 +271,37 @@ DatabaseBackendDispatcher::DatabaseBackendDispatcher(BackendDispatcher& backendD
     m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("Database"), this);
 }
 
-void DatabaseBackendDispatcher::dispatch(long callId, const String& method, Ref<InspectorObject>&& message)
+void DatabaseBackendDispatcher::dispatch(long requestId, const String& method, Ref<InspectorObject>&& message)
 {
     Ref<DatabaseBackendDispatcher> protect(*this);
 
+    RefPtr<InspectorObject> parameters;
+    message->getObject(ASCIILiteral("params"), parameters);
+
     if (method == "executeSQLSyncOptionalReturnValues")
-        executeSQLSyncOptionalReturnValues(callId, message);
+        executeSQLSyncOptionalReturnValues(requestId, WTF::move(parameters));
     else if (method == "executeSQLAsyncOptionalReturnValues")
-        executeSQLAsyncOptionalReturnValues(callId, message);
+        executeSQLAsyncOptionalReturnValues(requestId, WTF::move(parameters));
     else if (method == "executeSQLSync")
-        executeSQLSync(callId, message);
+        executeSQLSync(requestId, WTF::move(parameters));
     else if (method == "executeSQLAsync")
-        executeSQLAsync(callId, message);
+        executeSQLAsync(requestId, WTF::move(parameters));
     else
-        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::MethodNotFound, makeString('\'', "Database", '.', method, "' was not found"));
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::MethodNotFound, makeString('\'', "Database", '.', method, "' was not found"));
 }
 
-void DatabaseBackendDispatcher::executeSQLSyncOptionalReturnValues(long callId, const InspectorObject& message)
+void DatabaseBackendDispatcher::executeSQLSyncOptionalReturnValues(long requestId, RefPtr<InspectorObject>&& parameters)
 {
-    auto protocolErrors = Inspector::Protocol::Array<String>::create();
-    RefPtr<InspectorObject> paramsContainer;
-    message.getObject(ASCIILiteral("params"), paramsContainer);
-    int in_databaseId = BackendDispatcher::getInteger(paramsContainer.get(), ASCIILiteral("databaseId"), nullptr, protocolErrors.get());
-    String in_query = BackendDispatcher::getString(paramsContainer.get(), ASCIILiteral("query"), nullptr, protocolErrors.get());
-    if (protocolErrors->length()) {
-        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Database.executeSQLSyncOptionalReturnValues");
-        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::InvalidParams, errorMessage, WTF::move(protocolErrors));
+    int in_databaseId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("databaseId"), nullptr);
+    String in_query = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("query"), nullptr);
+    if (m_backendDispatcher->hasProtocolErrors()) {
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Database.executeSQLSyncOptionalReturnValues"));
         return;
     }
 
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
     if (m_alternateDispatcher) {
-        m_alternateDispatcher->executeSQLSyncOptionalReturnValues(callId, in_databaseId, in_query);
+        m_alternateDispatcher->executeSQLSyncOptionalReturnValues(requestId, in_databaseId, in_query);
         return;
     }
 #endif
@@ -342,7 +342,10 @@ void DatabaseBackendDispatcher::executeSQLSyncOptionalReturnValues(long callId,
         if (out_printColor.isAssigned())
             result->setString(ASCIILiteral("printColor"), out_printColor.getValue());
     }
-    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+    if (!error.length())
+        m_backendDispatcher->sendResponse(requestId, WTF::move(result));
+    else
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTF::move(error));
 }
 
 DatabaseBackendDispatcherHandler::ExecuteSQLAsyncOptionalReturnValuesCallback::ExecuteSQLAsyncOptionalReturnValuesCallback(Ref<BackendDispatcher>&& backendDispatcher, int id) : BackendDispatcher::CallbackBase(WTF::move(backendDispatcher), id) { }
@@ -370,57 +373,49 @@ void DatabaseBackendDispatcherHandler::ExecuteSQLAsyncOptionalReturnValuesCallba
         jsonMessage->setArray(ASCIILiteral("alternateColors"), alternateColors);
     if (printColor.isAssigned())
         jsonMessage->setString(ASCIILiteral("printColor"), printColor.getValue());
-    sendIfActive(WTF::move(jsonMessage), ErrorString());
+    CallbackBase::sendSuccess(WTF::move(jsonMessage));
 }
 
-void DatabaseBackendDispatcher::executeSQLAsyncOptionalReturnValues(long callId, const InspectorObject& message)
+void DatabaseBackendDispatcher::executeSQLAsyncOptionalReturnValues(long requestId, RefPtr<InspectorObject>&& parameters)
 {
-    auto protocolErrors = Inspector::Protocol::Array<String>::create();
-    RefPtr<InspectorObject> paramsContainer;
-    message.getObject(ASCIILiteral("params"), paramsContainer);
-    int in_databaseId = BackendDispatcher::getInteger(paramsContainer.get(), ASCIILiteral("databaseId"), nullptr, protocolErrors.get());
-    String in_query = BackendDispatcher::getString(paramsContainer.get(), ASCIILiteral("query"), nullptr, protocolErrors.get());
-    if (protocolErrors->length()) {
-        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Database.executeSQLAsyncOptionalReturnValues");
-        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::InvalidParams, errorMessage, WTF::move(protocolErrors));
+    int in_databaseId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("databaseId"), nullptr);
+    String in_query = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("query"), nullptr);
+    if (m_backendDispatcher->hasProtocolErrors()) {
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Database.executeSQLAsyncOptionalReturnValues"));
         return;
     }
 
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
     if (m_alternateDispatcher) {
-        m_alternateDispatcher->executeSQLAsyncOptionalReturnValues(callId, in_databaseId, in_query);
+        m_alternateDispatcher->executeSQLAsyncOptionalReturnValues(requestId, in_databaseId, in_query);
         return;
     }
 #endif
 
     ErrorString error;
     Ref<InspectorObject> result = InspectorObject::create();
-    Ref<DatabaseBackendDispatcherHandler::ExecuteSQLAsyncOptionalReturnValuesCallback> callback = adoptRef(*new DatabaseBackendDispatcherHandler::ExecuteSQLAsyncOptionalReturnValuesCallback(m_backendDispatcher.copyRef(), callId));
+    Ref<DatabaseBackendDispatcherHandler::ExecuteSQLAsyncOptionalReturnValuesCallback> callback = adoptRef(*new DatabaseBackendDispatcherHandler::ExecuteSQLAsyncOptionalReturnValuesCallback(m_backendDispatcher.copyRef(), requestId));
     m_agent->executeSQLAsyncOptionalReturnValues(error, in_databaseId, in_query, callback.copyRef());
 
     if (error.length()) {
         callback->disable();
-        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::ServerError, error);
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, error);
         return;
     }
 }
 
-void DatabaseBackendDispatcher::executeSQLSync(long callId, const InspectorObject& message)
+void DatabaseBackendDispatcher::executeSQLSync(long requestId, RefPtr<InspectorObject>&& parameters)
 {
-    auto protocolErrors = Inspector::Protocol::Array<String>::create();
-    RefPtr<InspectorObject> paramsContainer;
-    message.getObject(ASCIILiteral("params"), paramsContainer);
-    int in_databaseId = BackendDispatcher::getInteger(paramsContainer.get(), ASCIILiteral("databaseId"), nullptr, protocolErrors.get());
-    String in_query = BackendDispatcher::getString(paramsContainer.get(), ASCIILiteral("query"), nullptr, protocolErrors.get());
-    if (protocolErrors->length()) {
-        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Database.executeSQLSync");
-        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::InvalidParams, errorMessage, WTF::move(protocolErrors));
+    int in_databaseId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("databaseId"), nullptr);
+    String in_query = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("query"), nullptr);
+    if (m_backendDispatcher->hasProtocolErrors()) {
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Database.executeSQLSync"));
         return;
     }
 
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
     if (m_alternateDispatcher) {
-        m_alternateDispatcher->executeSQLSync(callId, in_databaseId, in_query);
+        m_alternateDispatcher->executeSQLSync(requestId, in_databaseId, in_query);
         return;
     }
 #endif
@@ -451,7 +446,10 @@ void DatabaseBackendDispatcher::executeSQLSync(long callId, const InspectorObjec
         result->setString(ASCIILiteral("screenColor"), Inspector::Protocol::getEnumConstantValue(out_screenColor));
         result->setString(ASCIILiteral("printColor"), Inspector::Protocol::getEnumConstantValue(out_printColor));
     }
-    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+    if (!error.length())
+        m_backendDispatcher->sendResponse(requestId, WTF::move(result));
+    else
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTF::move(error));
 }
 
 DatabaseBackendDispatcherHandler::ExecuteSQLAsyncCallback::ExecuteSQLAsyncCallback(Ref<BackendDispatcher>&& backendDispatcher, int id) : BackendDispatcher::CallbackBase(WTF::move(backendDispatcher), id) { }
@@ -469,37 +467,33 @@ void DatabaseBackendDispatcherHandler::ExecuteSQLAsyncCallback::sendSuccess(RefP
     jsonMessage->setString(ASCIILiteral("screenColor"), Inspector::Protocol::getEnumConstantValue(screenColor));
     jsonMessage->setArray(ASCIILiteral("alternateColors"), alternateColors);
     jsonMessage->setString(ASCIILiteral("printColor"), Inspector::Protocol::getEnumConstantValue(printColor));
-    sendIfActive(WTF::move(jsonMessage), ErrorString());
+    CallbackBase::sendSuccess(WTF::move(jsonMessage));
 }
 
-void DatabaseBackendDispatcher::executeSQLAsync(long callId, const InspectorObject& message)
+void DatabaseBackendDispatcher::executeSQLAsync(long requestId, RefPtr<InspectorObject>&& parameters)
 {
-    auto protocolErrors = Inspector::Protocol::Array<String>::create();
-    RefPtr<InspectorObject> paramsContainer;
-    message.getObject(ASCIILiteral("params"), paramsContainer);
-    int in_databaseId = BackendDispatcher::getInteger(paramsContainer.get(), ASCIILiteral("databaseId"), nullptr, protocolErrors.get());
-    String in_query = BackendDispatcher::getString(paramsContainer.get(), ASCIILiteral("query"), nullptr, protocolErrors.get());
-    if (protocolErrors->length()) {
-        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Database.executeSQLAsync");
-        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::InvalidParams, errorMessage, WTF::move(protocolErrors));
+    int in_databaseId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("databaseId"), nullptr);
+    String in_query = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("query"), nullptr);
+    if (m_backendDispatcher->hasProtocolErrors()) {
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Database.executeSQLAsync"));
         return;
     }
 
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
     if (m_alternateDispatcher) {
-        m_alternateDispatcher->executeSQLAsync(callId, in_databaseId, in_query);
+        m_alternateDispatcher->executeSQLAsync(requestId, in_databaseId, in_query);
         return;
     }
 #endif
 
     ErrorString error;
     Ref<InspectorObject> result = InspectorObject::create();
-    Ref<DatabaseBackendDispatcherHandler::ExecuteSQLAsyncCallback> callback = adoptRef(*new DatabaseBackendDispatcherHandler::ExecuteSQLAsyncCallback(m_backendDispatcher.copyRef(), callId));
+    Ref<DatabaseBackendDispatcherHandler::ExecuteSQLAsyncCallback> callback = adoptRef(*new DatabaseBackendDispatcherHandler::ExecuteSQLAsyncCallback(m_backendDispatcher.copyRef(), requestId));
     m_agent->executeSQLAsync(error, in_databaseId, in_query, callback.copyRef());
 
     if (error.length()) {
         callback->disable();
-        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::ServerError, error);
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, error);
         return;
     }
 }
@@ -851,10 +845,10 @@ namespace Inspector {
 class ObjCInspectorDatabaseBackendDispatcher final : public AlternateDatabaseBackendDispatcher {
 public:
     ObjCInspectorDatabaseBackendDispatcher(id<RWIProtocolDatabaseDomainHandler> handler) { m_delegate = handler; }
-    virtual void executeSQLSyncOptionalReturnValues(long callId, int in_databaseId, const String& in_query) override;
-    virtual void executeSQLAsyncOptionalReturnValues(long callId, int in_databaseId, const String& in_query) override;
-    virtual void executeSQLSync(long callId, int in_databaseId, const String& in_query) override;
-    virtual void executeSQLAsync(long callId, int in_databaseId, const String& in_query) override;
+    virtual void executeSQLSyncOptionalReturnValues(long requestId, int in_databaseId, const String& in_query) override;
+    virtual void executeSQLAsyncOptionalReturnValues(long requestId, int in_databaseId, const String& in_query) override;
+    virtual void executeSQLSync(long requestId, int in_databaseId, const String& in_query) override;
+    virtual void executeSQLAsync(long requestId, int in_databaseId, const String& in_query) override;
 private:
     RetainPtr<id<RWIProtocolDatabaseDomainHandler>> m_delegate;
 };
@@ -1033,10 +1027,11 @@ __attribute__((visibility ("default")))
 
 namespace Inspector {
 
-void ObjCInspectorDatabaseBackendDispatcher::executeSQLSyncOptionalReturnValues(long callId, int in_databaseId, const String& in_query)
+void ObjCInspectorDatabaseBackendDispatcher::executeSQLSyncOptionalReturnValues(long requestId, int in_databaseId, const String& in_query)
 {
     id errorCallback = ^(NSString *error) {
-        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
+        backendDispatcher()->sendPendingErrors();
     };
 
     id successCallback = ^(NSArray/*<NSString>*/ **columnNames, NSString **notes, double *timestamp, RWIProtocolJSONObject **values, RWIProtocolJSONObject **payload, int *databaseId, RWIProtocolDatabaseError **sqlError, RWIProtocolDatabasePrimaryColors *screenColor, NSArray/*<NSString>*/ **alternateColors, RWIProtocolDatabaseExecuteSQLSyncOptionalReturnValuesPrintColor *printColor) {
@@ -1067,7 +1062,7 @@ void ObjCInspectorDatabaseBackendDispatcher::executeSQLSyncOptionalReturnValues(
             resultObject->setArray(ASCIILiteral("alternateColors"), inspectorStringArray(*alternateColors));
         if (printColor)
             resultObject->setString(ASCIILiteral("printColor"), toProtocolString(*printColor));
-        backendDispatcher()->sendResponse(callId, WTF::move(resultObject), String());
+        backendDispatcher()->sendResponse(requestId, WTF::move(resultObject));
     };
 
     int o_in_databaseId = in_databaseId;
@@ -1076,10 +1071,11 @@ void ObjCInspectorDatabaseBackendDispatcher::executeSQLSyncOptionalReturnValues(
     [m_delegate executeSQLSyncOptionalReturnValuesWithErrorCallback:errorCallback successCallback:successCallback databaseId:o_in_databaseId query:o_in_query];
 }
 
-void ObjCInspectorDatabaseBackendDispatcher::executeSQLAsyncOptionalReturnValues(long callId, int in_databaseId, const String& in_query)
+void ObjCInspectorDatabaseBackendDispatcher::executeSQLAsyncOptionalReturnValues(long requestId, int in_databaseId, const String& in_query)
 {
     id errorCallback = ^(NSString *error) {
-        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
+        backendDispatcher()->sendPendingErrors();
     };
 
     id successCallback = ^(NSArray/*<NSString>*/ **columnNames, NSString **notes, double *timestamp, RWIProtocolJSONObject **values, RWIProtocolJSONObject **payload, int *databaseId, RWIProtocolDatabaseError **sqlError, RWIProtocolDatabasePrimaryColors *screenColor, NSArray/*<NSString>*/ **alternateColors, RWIProtocolDatabaseExecuteSQLAsyncOptionalReturnValuesPrintColor *printColor) {
@@ -1110,7 +1106,7 @@ void ObjCInspectorDatabaseBackendDispatcher::executeSQLAsyncOptionalReturnValues
             resultObject->setArray(ASCIILiteral("alternateColors"), inspectorStringArray(*alternateColors));
         if (printColor)
             resultObject->setString(ASCIILiteral("printColor"), toProtocolString(*printColor));
-        backendDispatcher()->sendResponse(callId, WTF::move(resultObject), String());
+        backendDispatcher()->sendResponse(requestId, WTF::move(resultObject));
     };
 
     int o_in_databaseId = in_databaseId;
@@ -1119,10 +1115,11 @@ void ObjCInspectorDatabaseBackendDispatcher::executeSQLAsyncOptionalReturnValues
     [m_delegate executeSQLAsyncOptionalReturnValuesWithErrorCallback:errorCallback successCallback:successCallback databaseId:o_in_databaseId query:o_in_query];
 }
 
-void ObjCInspectorDatabaseBackendDispatcher::executeSQLSync(long callId, int in_databaseId, const String& in_query)
+void ObjCInspectorDatabaseBackendDispatcher::executeSQLSync(long requestId, int in_databaseId, const String& in_query)
 {
     id errorCallback = ^(NSString *error) {
-        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
+        backendDispatcher()->sendPendingErrors();
     };
 
     id successCallback = ^(NSArray/*<NSString>*/ *columnNames, NSString *notes, double timestamp, RWIProtocolJSONObject *values, RWIProtocolJSONObject *payload, int databaseId, RWIProtocolDatabaseError *sqlError, NSArray/*<NSString>*/ *alternateColors, RWIProtocolDatabasePrimaryColors screenColor, RWIProtocolDatabaseExecuteSQLSyncPrintColor printColor) {
@@ -1143,7 +1140,7 @@ void ObjCInspectorDatabaseBackendDispatcher::executeSQLSync(long callId, int in_
         resultObject->setArray(ASCIILiteral("alternateColors"), inspectorStringArray(alternateColors));
         resultObject->setString(ASCIILiteral("screenColor"), toProtocolString(screenColor));
         resultObject->setString(ASCIILiteral("printColor"), toProtocolString(printColor));
-        backendDispatcher()->sendResponse(callId, WTF::move(resultObject), String());
+        backendDispatcher()->sendResponse(requestId, WTF::move(resultObject));
     };
 
     int o_in_databaseId = in_databaseId;
@@ -1152,10 +1149,11 @@ void ObjCInspectorDatabaseBackendDispatcher::executeSQLSync(long callId, int in_
     [m_delegate executeSQLSyncWithErrorCallback:errorCallback successCallback:successCallback databaseId:o_in_databaseId query:o_in_query];
 }
 
-void ObjCInspectorDatabaseBackendDispatcher::executeSQLAsync(long callId, int in_databaseId, const String& in_query)
+void ObjCInspectorDatabaseBackendDispatcher::executeSQLAsync(long requestId, int in_databaseId, const String& in_query)
 {
     id errorCallback = ^(NSString *error) {
-        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
+        backendDispatcher()->sendPendingErrors();
     };
 
     id successCallback = ^(NSArray/*<NSString>*/ *columnNames, NSString *notes, double timestamp, RWIProtocolJSONObject *values, RWIProtocolJSONObject *payload, int databaseId, RWIProtocolDatabaseError *sqlError, RWIProtocolDatabasePrimaryColors screenColor, NSArray/*<NSString>*/ *alternateColors, RWIProtocolDatabaseExecuteSQLAsyncPrintColor printColor) {
@@ -1176,7 +1174,7 @@ void ObjCInspectorDatabaseBackendDispatcher::executeSQLAsync(long callId, int in
         resultObject->setString(ASCIILiteral("screenColor"), toProtocolString(screenColor));
         resultObject->setArray(ASCIILiteral("alternateColors"), inspectorStringArray(alternateColors));
         resultObject->setString(ASCIILiteral("printColor"), toProtocolString(printColor));
-        backendDispatcher()->sendResponse(callId, WTF::move(resultObject), String());
+        backendDispatcher()->sendResponse(requestId, WTF::move(resultObject));
     };
 
     int o_in_databaseId = in_databaseId;
index e349ecf..bca7433 100644 (file)
@@ -170,10 +170,10 @@ protected:
 class DatabaseBackendDispatcher final : public SupplementalBackendDispatcher {
 public:
     static Ref<DatabaseBackendDispatcher> create(BackendDispatcher*, DatabaseBackendDispatcherHandler*);
-    virtual void dispatch(long callId, const String& method, Ref<InspectorObject>&& message) override;
+    virtual void dispatch(long requestId, const String& method, Ref<InspectorObject>&& message) override;
 private:
-    void executeAllOptionalParameters(long callId, const InspectorObject& message);
-    void executeNoOptionalParameters(long callId, const InspectorObject& message);
+    void executeAllOptionalParameters(long requestId, RefPtr<InspectorObject>&& parameters);
+    void executeNoOptionalParameters(long requestId, RefPtr<InspectorObject>&& parameters);
 private:
     DatabaseBackendDispatcher(BackendDispatcher&, DatabaseBackendDispatcherHandler*);
     DatabaseBackendDispatcherHandler* m_agent;
@@ -226,6 +226,7 @@ private:
 
 #include <inspector/InspectorFrontendChannel.h>
 #include <inspector/InspectorValues.h>
+#include <wtf/NeverDestroyed.h>
 #include <wtf/text/CString.h>
 
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
@@ -251,52 +252,51 @@ DatabaseBackendDispatcher::DatabaseBackendDispatcher(BackendDispatcher& backendD
     m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("Database"), this);
 }
 
-void DatabaseBackendDispatcher::dispatch(long callId, const String& method, Ref<InspectorObject>&& message)
+void DatabaseBackendDispatcher::dispatch(long requestId, const String& method, Ref<InspectorObject>&& message)
 {
     Ref<DatabaseBackendDispatcher> protect(*this);
 
+    RefPtr<InspectorObject> parameters;
+    message->getObject(ASCIILiteral("params"), parameters);
+
     if (method == "executeAllOptionalParameters")
-        executeAllOptionalParameters(callId, message);
+        executeAllOptionalParameters(requestId, WTF::move(parameters));
     else if (method == "executeNoOptionalParameters")
-        executeNoOptionalParameters(callId, message);
+        executeNoOptionalParameters(requestId, WTF::move(parameters));
     else
-        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::MethodNotFound, makeString('\'', "Database", '.', method, "' was not found"));
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::MethodNotFound, makeString('\'', "Database", '.', method, "' was not found"));
 }
 
-void DatabaseBackendDispatcher::executeAllOptionalParameters(long callId, const InspectorObject& message)
+void DatabaseBackendDispatcher::executeAllOptionalParameters(long requestId, RefPtr<InspectorObject>&& parameters)
 {
-    auto protocolErrors = Inspector::Protocol::Array<String>::create();
-    RefPtr<InspectorObject> paramsContainer;
-    message.getObject(ASCIILiteral("params"), paramsContainer);
     bool opt_in_columnNames_valueFound = false;
-    RefPtr<Inspector::InspectorArray> opt_in_columnNames = BackendDispatcher::getArray(paramsContainer.get(), ASCIILiteral("columnNames"), &opt_in_columnNames_valueFound, protocolErrors.get());
+    RefPtr<Inspector::InspectorArray> opt_in_columnNames = m_backendDispatcher->getArray(parameters.get(), ASCIILiteral("columnNames"), &opt_in_columnNames_valueFound);
     bool opt_in_notes_valueFound = false;
-    String opt_in_notes = BackendDispatcher::getString(paramsContainer.get(), ASCIILiteral("notes"), &opt_in_notes_valueFound, protocolErrors.get());
+    String opt_in_notes = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("notes"), &opt_in_notes_valueFound);
     bool opt_in_timestamp_valueFound = false;
-    Inspector::Protocol::OptOutput<double> opt_in_timestamp = BackendDispatcher::getDouble(paramsContainer.get(), ASCIILiteral("timestamp"), &opt_in_timestamp_valueFound, protocolErrors.get());
+    Inspector::Protocol::OptOutput<double> opt_in_timestamp = m_backendDispatcher->getDouble(parameters.get(), ASCIILiteral("timestamp"), &opt_in_timestamp_valueFound);
     bool opt_in_values_valueFound = false;
-    RefPtr<Inspector::InspectorObject> opt_in_values = BackendDispatcher::getObject(paramsContainer.get(), ASCIILiteral("values"), &opt_in_values_valueFound, protocolErrors.get());
+    RefPtr<Inspector::InspectorObject> opt_in_values = m_backendDispatcher->getObject(parameters.get(), ASCIILiteral("values"), &opt_in_values_valueFound);
     bool opt_in_payload_valueFound = false;
-    RefPtr<Inspector::InspectorValue> opt_in_payload = BackendDispatcher::getValue(paramsContainer.get(), ASCIILiteral("payload"), &opt_in_payload_valueFound, protocolErrors.get());
+    RefPtr<Inspector::InspectorValue> opt_in_payload = m_backendDispatcher->getValue(parameters.get(), ASCIILiteral("payload"), &opt_in_payload_valueFound);
     bool opt_in_databaseId_valueFound = false;
-    int opt_in_databaseId = BackendDispatcher::getInteger(paramsContainer.get(), ASCIILiteral("databaseId"), &opt_in_databaseId_valueFound, protocolErrors.get());
+    int opt_in_databaseId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("databaseId"), &opt_in_databaseId_valueFound);
     bool opt_in_sqlError_valueFound = false;
-    RefPtr<Inspector::InspectorObject> opt_in_sqlError = BackendDispatcher::getObject(paramsContainer.get(), ASCIILiteral("sqlError"), &opt_in_sqlError_valueFound, protocolErrors.get());
+    RefPtr<Inspector::InspectorObject> opt_in_sqlError = m_backendDispatcher->getObject(parameters.get(), ASCIILiteral("sqlError"), &opt_in_sqlError_valueFound);
     bool opt_in_screenColor_valueFound = false;
-    String opt_in_screenColor = BackendDispatcher::getString(paramsContainer.get(), ASCIILiteral("screenColor"), &opt_in_screenColor_valueFound, protocolErrors.get());
+    String opt_in_screenColor = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("screenColor"), &opt_in_screenColor_valueFound);
     bool opt_in_alternateColors_valueFound = false;
-    RefPtr<Inspector::InspectorArray> opt_in_alternateColors = BackendDispatcher::getArray(paramsContainer.get(), ASCIILiteral("alternateColors"), &opt_in_alternateColors_valueFound, protocolErrors.get());
+    RefPtr<Inspector::InspectorArray> opt_in_alternateColors = m_backendDispatcher->getArray(parameters.get(), ASCIILiteral("alternateColors"), &opt_in_alternateColors_valueFound);
     bool opt_in_printColor_valueFound = false;
-    String opt_in_printColor = BackendDispatcher::getString(paramsContainer.get(), ASCIILiteral("printColor"), &opt_in_printColor_valueFound, protocolErrors.get());
-    if (protocolErrors->length()) {
-        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Database.executeAllOptionalParameters");
-        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::InvalidParams, errorMessage, WTF::move(protocolErrors));
+    String opt_in_printColor = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("printColor"), &opt_in_printColor_valueFound);
+    if (m_backendDispatcher->hasProtocolErrors()) {
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Database.executeAllOptionalParameters"));
         return;
     }
 
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
     if (m_alternateDispatcher) {
-        m_alternateDispatcher->executeAllOptionalParameters(callId, opt_in_columnNames_valueFound ? opt_in_columnNames.get() : nullptr, opt_in_notes_valueFound ? &opt_in_notes : nullptr, opt_in_timestamp_valueFound ? &opt_in_timestamp : nullptr, opt_in_values_valueFound ? opt_in_values.get() : nullptr, opt_in_payload_valueFound ? opt_in_payload.get() : nullptr, opt_in_databaseId_valueFound ? &opt_in_databaseId : nullptr, opt_in_sqlError_valueFound ? opt_in_sqlError.get() : nullptr, opt_in_screenColor_valueFound ? &opt_in_screenColor : nullptr, opt_in_alternateColors_valueFound ? opt_in_alternateColors.get() : nullptr, opt_in_printColor_valueFound ? &opt_in_printColor : nullptr);
+        m_alternateDispatcher->executeAllOptionalParameters(requestId, opt_in_columnNames_valueFound ? opt_in_columnNames.get() : nullptr, opt_in_notes_valueFound ? &opt_in_notes : nullptr, opt_in_timestamp_valueFound ? &opt_in_timestamp : nullptr, opt_in_values_valueFound ? opt_in_values.get() : nullptr, opt_in_payload_valueFound ? opt_in_payload.get() : nullptr, opt_in_databaseId_valueFound ? &opt_in_databaseId : nullptr, opt_in_sqlError_valueFound ? opt_in_sqlError.get() : nullptr, opt_in_screenColor_valueFound ? &opt_in_screenColor : nullptr, opt_in_alternateColors_valueFound ? opt_in_alternateColors.get() : nullptr, opt_in_printColor_valueFound ? &opt_in_printColor : nullptr);
         return;
     }
 #endif
@@ -337,33 +337,32 @@ void DatabaseBackendDispatcher::executeAllOptionalParameters(long callId, const
         if (out_printColor.isAssigned())
             result->setString(ASCIILiteral("printColor"), out_printColor.getValue());
     }
-    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+    if (!error.length())
+        m_backendDispatcher->sendResponse(requestId, WTF::move(result));
+    else
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTF::move(error));
 }
 
-void DatabaseBackendDispatcher::executeNoOptionalParameters(long callId, const InspectorObject& message)
+void DatabaseBackendDispatcher::executeNoOptionalParameters(long requestId, RefPtr<InspectorObject>&& parameters)
 {
-    auto protocolErrors = Inspector::Protocol::Array<String>::create();
-    RefPtr<InspectorObject> paramsContainer;
-    message.getObject(ASCIILiteral("params"), paramsContainer);
-    RefPtr<Inspector::InspectorArray> in_columnNames = BackendDispatcher::getArray(paramsContainer.get(), ASCIILiteral("columnNames"), nullptr, protocolErrors.get());
-    String in_notes = BackendDispatcher::getString(paramsContainer.get(), ASCIILiteral("notes"), nullptr, protocolErrors.get());
-    double in_timestamp = BackendDispatcher::getDouble(paramsContainer.get(), ASCIILiteral("timestamp"), nullptr, protocolErrors.get());
-    RefPtr<Inspector::InspectorObject> in_values = BackendDispatcher::getObject(paramsContainer.get(), ASCIILiteral("values"), nullptr, protocolErrors.get());
-    RefPtr<Inspector::InspectorValue> in_payload = BackendDispatcher::getValue(paramsContainer.get(), ASCIILiteral("payload"), nullptr, protocolErrors.get());
-    int in_databaseId = BackendDispatcher::getInteger(paramsContainer.get(), ASCIILiteral("databaseId"), nullptr, protocolErrors.get());
-    RefPtr<Inspector::InspectorObject> in_sqlError = BackendDispatcher::getObject(paramsContainer.get(), ASCIILiteral("sqlError"), nullptr, protocolErrors.get());
-    String in_screenColor = BackendDispatcher::getString(paramsContainer.get(), ASCIILiteral("screenColor"), nullptr, protocolErrors.get());
-    RefPtr<Inspector::InspectorArray> in_alternateColors = BackendDispatcher::getArray(paramsContainer.get(), ASCIILiteral("alternateColors"), nullptr, protocolErrors.get());
-    String in_printColor = BackendDispatcher::getString(paramsContainer.get(), ASCIILiteral("printColor"), nullptr, protocolErrors.get());
-    if (protocolErrors->length()) {
-        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Database.executeNoOptionalParameters");
-        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::InvalidParams, errorMessage, WTF::move(protocolErrors));
+    RefPtr<Inspector::InspectorArray> in_columnNames = m_backendDispatcher->getArray(parameters.get(), ASCIILiteral("columnNames"), nullptr);
+    String in_notes = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("notes"), nullptr);
+    double in_timestamp = m_backendDispatcher->getDouble(parameters.get(), ASCIILiteral("timestamp"), nullptr);
+    RefPtr<Inspector::InspectorObject> in_values = m_backendDispatcher->getObject(parameters.get(), ASCIILiteral("values"), nullptr);
+    RefPtr<Inspector::InspectorValue> in_payload = m_backendDispatcher->getValue(parameters.get(), ASCIILiteral("payload"), nullptr);
+    int in_databaseId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("databaseId"), nullptr);
+    RefPtr<Inspector::InspectorObject> in_sqlError = m_backendDispatcher->getObject(parameters.get(), ASCIILiteral("sqlError"), nullptr);
+    String in_screenColor = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("screenColor"), nullptr);
+    RefPtr<Inspector::InspectorArray> in_alternateColors = m_backendDispatcher->getArray(parameters.get(), ASCIILiteral("alternateColors"), nullptr);
+    String in_printColor = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("printColor"), nullptr);
+    if (m_backendDispatcher->hasProtocolErrors()) {
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Database.executeNoOptionalParameters"));
         return;
     }
 
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
     if (m_alternateDispatcher) {
-        m_alternateDispatcher->executeNoOptionalParameters(callId, *in_columnNames, in_notes, in_timestamp, *in_values, *in_payload, in_databaseId, *in_sqlError, in_screenColor, *in_alternateColors, in_printColor);
+        m_alternateDispatcher->executeNoOptionalParameters(requestId, *in_columnNames, in_notes, in_timestamp, *in_values, *in_payload, in_databaseId, *in_sqlError, in_screenColor, *in_alternateColors, in_printColor);
         return;
     }
 #endif
@@ -394,7 +393,10 @@ void DatabaseBackendDispatcher::executeNoOptionalParameters(long callId, const I
         result->setArray(ASCIILiteral("alternateColors"), out_alternateColors);
         result->setString(ASCIILiteral("printColor"), Inspector::Protocol::getEnumConstantValue(out_printColor));
     }
-    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+    if (!error.length())
+        m_backendDispatcher->sendResponse(requestId, WTF::move(result));
+    else
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTF::move(error));
 }
 
 } // namespace Inspector
@@ -744,8 +746,8 @@ namespace Inspector {
 class ObjCInspectorDatabaseBackendDispatcher final : public AlternateDatabaseBackendDispatcher {
 public:
     ObjCInspectorDatabaseBackendDispatcher(id<RWIProtocolDatabaseDomainHandler> handler) { m_delegate = handler; }
-    virtual void executeAllOptionalParameters(long callId, const Inspector::InspectorArray* in_columnNames, const String* in_notes, const double* in_timestamp, const Inspector::InspectorObject* in_values, const Inspector::InspectorValue* in_payload, const int* in_databaseId, const Inspector::InspectorObject* in_sqlError, const String* in_screenColor, const Inspector::InspectorArray* in_alternateColors, const String* in_printColor) override;
-    virtual void executeNoOptionalParameters(long callId, const Inspector::InspectorArray& in_columnNames, const String& in_notes, double in_timestamp, const Inspector::InspectorObject& in_values, Inspector::InspectorValue in_payload, int in_databaseId, const Inspector::InspectorObject& in_sqlError, const String& in_screenColor, const Inspector::InspectorArray& in_alternateColors, const String& in_printColor) override;
+    virtual void executeAllOptionalParameters(long requestId, const Inspector::InspectorArray* in_columnNames, const String* in_notes, const double* in_timestamp, const Inspector::InspectorObject* in_values, const Inspector::InspectorValue* in_payload, const int* in_databaseId, const Inspector::InspectorObject* in_sqlError, const String* in_screenColor, const Inspector::InspectorArray* in_alternateColors, const String* in_printColor) override;
+    virtual void executeNoOptionalParameters(long requestId, const Inspector::InspectorArray& in_columnNames, const String& in_notes, double in_timestamp, const Inspector::InspectorObject& in_values, Inspector::InspectorValue in_payload, int in_databaseId, const Inspector::InspectorObject& in_sqlError, const String& in_screenColor, const Inspector::InspectorArray& in_alternateColors, const String& in_printColor) override;
 private:
     RetainPtr<id<RWIProtocolDatabaseDomainHandler>> m_delegate;
 };
@@ -924,10 +926,11 @@ __attribute__((visibility ("default")))
 
 namespace Inspector {
 
-void ObjCInspectorDatabaseBackendDispatcher::executeAllOptionalParameters(long callId, const Inspector::InspectorArray* in_columnNames, const String* in_notes, const double* in_timestamp, const Inspector::InspectorObject* in_values, const Inspector::InspectorValue* in_payload, const int* in_databaseId, const Inspector::InspectorObject* in_sqlError, const String* in_screenColor, const Inspector::InspectorArray* in_alternateColors, const String* in_printColor)
+void ObjCInspectorDatabaseBackendDispatcher::executeAllOptionalParameters(long requestId, const Inspector::InspectorArray* in_columnNames, const String* in_notes, const double* in_timestamp, const Inspector::InspectorObject* in_values, const Inspector::InspectorValue* in_payload, const int* in_databaseId, const Inspector::InspectorObject* in_sqlError, const String* in_screenColor, const Inspector::InspectorArray* in_alternateColors, const String* in_printColor)
 {
     id errorCallback = ^(NSString *error) {
-        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
+        backendDispatcher()->sendPendingErrors();
     };
 
     id successCallback = ^(NSArray/*<NSString>*/ **columnNames, NSString **notes, double *timestamp, RWIProtocolJSONObject **values, RWIProtocolJSONObject **payload, int *databaseId, RWIProtocolDatabaseError **sqlError, RWIProtocolDatabasePrimaryColors *screenColor, NSArray/*<NSString>*/ **alternateColors, RWIProtocolDatabaseExecuteAllOptionalParametersPrintColor *printColor) {
@@ -958,7 +961,7 @@ void ObjCInspectorDatabaseBackendDispatcher::executeAllOptionalParameters(long c
             resultObject->setArray(ASCIILiteral("alternateColors"), inspectorStringArray(*alternateColors));
         if (printColor)
             resultObject->setString(ASCIILiteral("printColor"), toProtocolString(*printColor));
-        backendDispatcher()->sendResponse(callId, WTF::move(resultObject), String());
+        backendDispatcher()->sendResponse(requestId, WTF::move(resultObject));
     };
 
     NSArray/*<NSString>*/ *o_in_columnNames;
@@ -995,10 +998,11 @@ void ObjCInspectorDatabaseBackendDispatcher::executeAllOptionalParameters(long c
     [m_delegate executeAllOptionalParametersWithErrorCallback:errorCallback successCallback:successCallback columnNames:(in_columnNames ? &o_in_columnNames : nil) notes:(in_notes ? &o_in_notes : nil) timestamp:(in_timestamp ? &o_in_timestamp : nil) values:(in_values ? &o_in_values : nil) payload:(in_payload ? &o_in_payload : nil) databaseId:(in_databaseId ? &o_in_databaseId : nil) sqlError:(in_sqlError ? &o_in_sqlError : nil) screenColor:(in_screenColor ? &o_in_screenColor : nil) alternateColors:(in_alternateColors ? &o_in_alternateColors : nil) printColor:(in_printColor ? &o_in_printColor : nil)];
 }
 
-void ObjCInspectorDatabaseBackendDispatcher::executeNoOptionalParameters(long callId, const Inspector::InspectorArray& in_columnNames, const String& in_notes, double in_timestamp, const Inspector::InspectorObject& in_values, Inspector::InspectorValue in_payload, int in_databaseId, const Inspector::InspectorObject& in_sqlError, const String& in_screenColor, const Inspector::InspectorArray& in_alternateColors, const String& in_printColor)
+void ObjCInspectorDatabaseBackendDispatcher::executeNoOptionalParameters(long requestId, const Inspector::InspectorArray& in_columnNames, const String& in_notes, double in_timestamp, const Inspector::InspectorObject& in_values, Inspector::InspectorValue in_payload, int in_databaseId, const Inspector::InspectorObject& in_sqlError, const String& in_screenColor, const Inspector::InspectorArray& in_alternateColors, const String& in_printColor)
 {
     id errorCallback = ^(NSString *error) {
-        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
+        backendDispatcher()->sendPendingErrors();
     };
 
     id successCallback = ^(NSArray/*<NSString>*/ *columnNames, NSString *notes, double timestamp, RWIProtocolJSONObject *values, RWIProtocolJSONObject *payload, int databaseId, RWIProtocolDatabaseError *sqlError, RWIProtocolDatabasePrimaryColors screenColor, NSArray/*<NSString>*/ *alternateColors, RWIProtocolDatabaseExecuteNoOptionalParametersPrintColor printColor) {
@@ -1019,7 +1023,7 @@ void ObjCInspectorDatabaseBackendDispatcher::executeNoOptionalParameters(long ca
         resultObject->setString(ASCIILiteral("screenColor"), toProtocolString(screenColor));
         resultObject->setArray(ASCIILiteral("alternateColors"), inspectorStringArray(alternateColors));
         resultObject->setString(ASCIILiteral("printColor"), toProtocolString(printColor));
-        backendDispatcher()->sendResponse(callId, WTF::move(resultObject), String());
+        backendDispatcher()->sendResponse(requestId, WTF::move(resultObject));
     };
 
     NSArray/*<NSString>*/ *o_in_columnNames = objcStringArray(&in_columnNames);
index 190b260..c4cf6b1 100644 (file)
@@ -188,9 +188,9 @@ protected:
 class Network1BackendDispatcher final : public SupplementalBackendDispatcher {
 public:
     static Ref<Network1BackendDispatcher> create(BackendDispatcher*, Network1BackendDispatcherHandler*);
-    virtual void dispatch(long callId, const String& method, Ref<InspectorObject>&& message) override;
+    virtual void dispatch(long requestId, const String& method, Ref<InspectorObject>&& message) override;
 private:
-    void loadResource1(long callId, const InspectorObject& message);
+    void loadResource1(long requestId, RefPtr<InspectorObject>&& parameters);
 private:
     Network1BackendDispatcher(BackendDispatcher&, Network1BackendDispatcherHandler*);
     Network1BackendDispatcherHandler* m_agent;
@@ -205,15 +205,15 @@ private:
 class Network3BackendDispatcher final : public SupplementalBackendDispatcher {
 public:
     static Ref<Network3BackendDispatcher> create(BackendDispatcher*, Network3BackendDispatcherHandler*);
-    virtual void dispatch(long callId, const String& method, Ref<InspectorObject>&& message) override;
+    virtual void dispatch(long requestId, const String& method, Ref<InspectorObject>&& message) override;
 private:
-    void loadResource1(long callId, const InspectorObject& message);
-    void loadResource2(long callId, const InspectorObject& message);
-    void loadResource3(long callId, const InspectorObject& message);
-    void loadResource4(long callId, const InspectorObject& message);
-    void loadResource5(long callId, const InspectorObject& message);
-    void loadResource6(long callId, const InspectorObject& message);
-    void loadResource7(long callId, const InspectorObject& message);
+    void loadResource1(long requestId, RefPtr<InspectorObject>&& parameters);
+    void loadResource2(long requestId, RefPtr<InspectorObject>&& parameters);
+    void loadResource3(long requestId, RefPtr<InspectorObject>&& parameters);
+    void loadResource4(long requestId, RefPtr<InspectorObject>&& parameters);
+    void loadResource5(long requestId, RefPtr<InspectorObject>&& parameters);
+    void loadResource6(long requestId, RefPtr<InspectorObject>&& parameters);
+    void loadResource7(long requestId, RefPtr<InspectorObject>&& parameters);
 private:
     Network3BackendDispatcher(BackendDispatcher&, Network3BackendDispatcherHandler*);
     Network3BackendDispatcherHandler* m_agent;
@@ -266,6 +266,7 @@ private:
 
 #include <inspector/InspectorFrontendChannel.h>
 #include <inspector/InspectorValues.h>
+#include <wtf/NeverDestroyed.h>
 #include <wtf/text/CString.h>
 
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
@@ -292,21 +293,24 @@ Network1BackendDispatcher::Network1BackendDispatcher(BackendDispatcher& backendD
     m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("Network1"), this);
 }
 
-void Network1BackendDispatcher::dispatch(long callId, const String& method, Ref<InspectorObject>&& message)
+void Network1BackendDispatcher::dispatch(long requestId, const String& method, Ref<InspectorObject>&& message)
 {
     Ref<Network1BackendDispatcher> protect(*this);
 
+    RefPtr<InspectorObject> parameters;
+    message->getObject(ASCIILiteral("params"), parameters);
+
     if (method == "loadResource1")
-        loadResource1(callId, message);
+        loadResource1(requestId, WTF::move(parameters));
     else
-        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::MethodNotFound, makeString('\'', "Network1", '.', method, "' was not found"));
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::MethodNotFound, makeString('\'', "Network1", '.', method, "' was not found"));
 }
 
-void Network1BackendDispatcher::loadResource1(long callId, const InspectorObject&)
+void Network1BackendDispatcher::loadResource1(long requestId, RefPtr<InspectorObject>&&)
 {
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
     if (m_alternateDispatcher) {
-        m_alternateDispatcher->loadResource1(callId);
+        m_alternateDispatcher->loadResource1(requestId);
         return;
     }
 #endif
@@ -315,7 +319,10 @@ void Network1BackendDispatcher::loadResource1(long callId, const InspectorObject
     Ref<InspectorObject> result = InspectorObject::create();
     m_agent->loadResource1(error);
 
-    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+    if (!error.length())
+        m_backendDispatcher->sendResponse(requestId, WTF::move(result));
+    else
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTF::move(error));
 }
 
 Ref<Network3BackendDispatcher> Network3BackendDispatcher::create(BackendDispatcher* backendDispatcher, Network3BackendDispatcherHandler* agent)
@@ -333,14 +340,17 @@ Network3BackendDispatcher::Network3BackendDispatcher(BackendDispatcher& backendD
     m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("Network3"), this);
 }
 
-void Network3BackendDispatcher::dispatch(long callId, const String& method, Ref<InspectorObject>&& message)
+void Network3BackendDispatcher::dispatch(long requestId, const String& method, Ref<InspectorObject>&& message)
 {
     Ref<Network3BackendDispatcher> protect(*this);
 
-    typedef void (Network3BackendDispatcher::*CallHandler)(long callId, const InspectorObject& message);
+    RefPtr<InspectorObject> parameters;
+    message->getObject(ASCIILiteral("params"), parameters);
+
+    typedef void (Network3BackendDispatcher::*CallHandler)(long requestId, RefPtr<InspectorObject>&& message);
     typedef HashMap<String, CallHandler> DispatchMap;
-    DEPRECATED_DEFINE_STATIC_LOCAL(DispatchMap, dispatchMap, ());
-    if (dispatchMap.isEmpty()) {
+    static NeverDestroyed<DispatchMap> dispatchMap;
+    if (dispatchMap.get().isEmpty()) {
         static const struct MethodTable {
             const char* name;
             CallHandler handler;
@@ -355,23 +365,23 @@ void Network3BackendDispatcher::dispatch(long callId, const String& method, Ref<
         };
         size_t length = WTF_ARRAY_LENGTH(commands);
         for (size_t i = 0; i < length; ++i)
-            dispatchMap.add(commands[i].name, commands[i].handler);
+            dispatchMap.get().add(commands[i].name, commands[i].handler);
     }
 
-    HashMap<String, CallHandler>::iterator it = dispatchMap.find(method);
-    if (it == dispatchMap.end()) {
-        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::MethodNotFound, makeString('\'', "Network3", '.', method, "' was not found"));
+    auto findResult = dispatchMap.get().find(method);
+    if (findResult == dispatchMap.get().end()) {
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::MethodNotFound, makeString('\'', "Network3", '.', method, "' was not found"));
         return;
     }
 
-    ((*this).*it->value)(callId, message.get());
+    ((*this).*findResult->value)(requestId, WTF::move(parameters));
 }
 
-void Network3BackendDispatcher::loadResource1(long callId, const InspectorObject&)
+void Network3BackendDispatcher::loadResource1(long requestId, RefPtr<InspectorObject>&&)
 {
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
     if (m_alternateDispatcher) {
-        m_alternateDispatcher->loadResource1(callId);
+        m_alternateDispatcher->loadResource1(requestId);
         return;
     }
 #endif
@@ -380,14 +390,17 @@ void Network3BackendDispatcher::loadResource1(long callId, const InspectorObject
     Ref<InspectorObject> result = InspectorObject::create();
     m_agent->loadResource1(error);
 
-    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+    if (!error.length())
+        m_backendDispatcher->sendResponse(requestId, WTF::move(result));
+    else
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTF::move(error));
 }
 
-void Network3BackendDispatcher::loadResource2(long callId, const InspectorObject&)
+void Network3BackendDispatcher::loadResource2(long requestId, RefPtr<InspectorObject>&&)
 {
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
     if (m_alternateDispatcher) {
-        m_alternateDispatcher->loadResource2(callId);
+        m_alternateDispatcher->loadResource2(requestId);
         return;
     }
 #endif
@@ -396,14 +409,17 @@ void Network3BackendDispatcher::loadResource2(long callId, const InspectorObject
     Ref<InspectorObject> result = InspectorObject::create();
     m_agent->loadResource2(error);
 
-    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+    if (!error.length())
+        m_backendDispatcher->sendResponse(requestId, WTF::move(result));
+    else
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTF::move(error));
 }
 
-void Network3BackendDispatcher::loadResource3(long callId, const InspectorObject&)
+void Network3BackendDispatcher::loadResource3(long requestId, RefPtr<InspectorObject>&&)
 {
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
     if (m_alternateDispatcher) {
-        m_alternateDispatcher->loadResource3(callId);
+        m_alternateDispatcher->loadResource3(requestId);
         return;
     }
 #endif
@@ -412,14 +428,17 @@ void Network3BackendDispatcher::loadResource3(long callId, const InspectorObject
     Ref<InspectorObject> result = InspectorObject::create();
     m_agent->loadResource3(error);
 
-    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+    if (!error.length())
+        m_backendDispatcher->sendResponse(requestId, WTF::move(result));
+    else
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTF::move(error));
 }
 
-void Network3BackendDispatcher::loadResource4(long callId, const InspectorObject&)
+void Network3BackendDispatcher::loadResource4(long requestId, RefPtr<InspectorObject>&&)
 {
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
     if (m_alternateDispatcher) {
-        m_alternateDispatcher->loadResource4(callId);
+        m_alternateDispatcher->loadResource4(requestId);
         return;
     }
 #endif
@@ -428,14 +447,17 @@ void Network3BackendDispatcher::loadResource4(long callId, const InspectorObject
     Ref<InspectorObject> result = InspectorObject::create();
     m_agent->loadResource4(error);
 
-    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+    if (!error.length())
+        m_backendDispatcher->sendResponse(requestId, WTF::move(result));
+    else
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTF::move(error));
 }
 
-void Network3BackendDispatcher::loadResource5(long callId, const InspectorObject&)
+void Network3BackendDispatcher::loadResource5(long requestId, RefPtr<InspectorObject>&&)
 {
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
     if (m_alternateDispatcher) {
-        m_alternateDispatcher->loadResource5(callId);
+        m_alternateDispatcher->loadResource5(requestId);
         return;
     }
 #endif
@@ -444,14 +466,17 @@ void Network3BackendDispatcher::loadResource5(long callId, const InspectorObject
     Ref<InspectorObject> result = InspectorObject::create();
     m_agent->loadResource5(error);
 
-    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+    if (!error.length())
+        m_backendDispatcher->sendResponse(requestId, WTF::move(result));
+    else
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTF::move(error));
 }
 
-void Network3BackendDispatcher::loadResource6(long callId, const InspectorObject&)
+void Network3BackendDispatcher::loadResource6(long requestId, RefPtr<InspectorObject>&&)
 {
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
     if (m_alternateDispatcher) {
-        m_alternateDispatcher->loadResource6(callId);
+        m_alternateDispatcher->loadResource6(requestId);
         return;
     }
 #endif
@@ -460,14 +485,17 @@ void Network3BackendDispatcher::loadResource6(long callId, const InspectorObject
     Ref<InspectorObject> result = InspectorObject::create();
     m_agent->loadResource6(error);
 
-    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+    if (!error.length())
+        m_backendDispatcher->sendResponse(requestId, WTF::move(result));
+    else
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTF::move(error));
 }
 
-void Network3BackendDispatcher::loadResource7(long callId, const InspectorObject&)
+void Network3BackendDispatcher::loadResource7(long requestId, RefPtr<InspectorObject>&&)
 {
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
     if (m_alternateDispatcher) {
-        m_alternateDispatcher->loadResource7(callId);
+        m_alternateDispatcher->loadResource7(requestId);
         return;
     }
 #endif
@@ -476,7 +504,10 @@ void Network3BackendDispatcher::loadResource7(long callId, const InspectorObject
     Ref<InspectorObject> result = InspectorObject::create();
     m_agent->loadResource7(error);
 
-    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+    if (!error.length())
+        m_backendDispatcher->sendResponse(requestId, WTF::move(result));
+    else
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTF::move(error));
 }
 
 } // namespace Inspector
@@ -739,7 +770,7 @@ namespace Inspector {
 class ObjCInspectorNetwork1BackendDispatcher final : public AlternateNetwork1BackendDispatcher {
 public:
     ObjCInspectorNetwork1BackendDispatcher(id<RWIProtocolNetwork1DomainHandler> handler) { m_delegate = handler; }
-    virtual void loadResource1(long callId) override;
+    virtual void loadResource1(long requestId) override;
 private:
     RetainPtr<id<RWIProtocolNetwork1DomainHandler>> m_delegate;
 };
@@ -749,13 +780,13 @@ private:
 class ObjCInspectorNetwork3BackendDispatcher final : public AlternateNetwork3BackendDispatcher {
 public:
     ObjCInspectorNetwork3BackendDispatcher(id<RWIProtocolNetwork3DomainHandler> handler) { m_delegate = handler; }
-    virtual void loadResource1(long callId) override;
-    virtual void loadResource2(long callId) override;
-    virtual void loadResource3(long callId) override;
-    virtual void loadResource4(long callId) override;
-    virtual void loadResource5(long callId) override;
-    virtual void loadResource6(long callId) override;
-    virtual void loadResource7(long callId) override;
+    virtual void loadResource1(long requestId) override;
+    virtual void loadResource2(long requestId) override;
+    virtual void loadResource3(long requestId) override;
+    virtual void loadResource4(long requestId) override;
+    virtual void loadResource5(long requestId) override;
+    virtual void loadResource6(long requestId) override;
+    virtual void loadResource7(long requestId) override;
 private:
     RetainPtr<id<RWIProtocolNetwork3DomainHandler>> m_delegate;
 };
@@ -955,14 +986,15 @@ __attribute__((visibility ("default")))
 
 namespace Inspector {
 
-void ObjCInspectorNetwork1BackendDispatcher::loadResource1(long callId)
+void ObjCInspectorNetwork1BackendDispatcher::loadResource1(long requestId)
 {
     id errorCallback = ^(NSString *error) {
-        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
+        backendDispatcher()->sendPendingErrors();
     };
 
     id successCallback = ^{
-        backendDispatcher()->sendResponse(callId, InspectorObject::create(), String());
+        backendDispatcher()->sendResponse(requestId, InspectorObject::create());
     };
 
     [m_delegate loadResource1WithErrorCallback:errorCallback successCallback:successCallback];
@@ -971,92 +1003,99 @@ void ObjCInspectorNetwork1BackendDispatcher::loadResource1(long callId)
 
 
 
-void ObjCInspectorNetwork3BackendDispatcher::loadResource1(long callId)
+void ObjCInspectorNetwork3BackendDispatcher::loadResource1(long requestId)
 {
     id errorCallback = ^(NSString *error) {
-        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
+        backendDispatcher()->sendPendingErrors();
     };
 
     id successCallback = ^{
-        backendDispatcher()->sendResponse(callId, InspectorObject::create(), String());
+        backendDispatcher()->sendResponse(requestId, InspectorObject::create());
     };
 
     [m_delegate loadResource1WithErrorCallback:errorCallback successCallback:successCallback];
 }
 
-void ObjCInspectorNetwork3BackendDispatcher::loadResource2(long callId)
+void ObjCInspectorNetwork3BackendDispatcher::loadResource2(long requestId)
 {
     id errorCallback = ^(NSString *error) {
-        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
+        backendDispatcher()->sendPendingErrors();
     };
 
     id successCallback = ^{
-        backendDispatcher()->sendResponse(callId, InspectorObject::create(), String());
+        backendDispatcher()->sendResponse(requestId, InspectorObject::create());
     };
 
     [m_delegate loadResource2WithErrorCallback:errorCallback successCallback:successCallback];
 }
 
-void ObjCInspectorNetwork3BackendDispatcher::loadResource3(long callId)
+void ObjCInspectorNetwork3BackendDispatcher::loadResource3(long requestId)
 {
     id errorCallback = ^(NSString *error) {
-        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
+        backendDispatcher()->sendPendingErrors();
     };
 
     id successCallback = ^{
-        backendDispatcher()->sendResponse(callId, InspectorObject::create(), String());
+        backendDispatcher()->sendResponse(requestId, InspectorObject::create());
     };
 
     [m_delegate loadResource3WithErrorCallback:errorCallback successCallback:successCallback];
 }
 
-void ObjCInspectorNetwork3BackendDispatcher::loadResource4(long callId)
+void ObjCInspectorNetwork3BackendDispatcher::loadResource4(long requestId)
 {
     id errorCallback = ^(NSString *error) {
-        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
+        backendDispatcher()->sendPendingErrors();
     };
 
     id successCallback = ^{
-        backendDispatcher()->sendResponse(callId, InspectorObject::create(), String());
+        backendDispatcher()->sendResponse(requestId, InspectorObject::create());
     };
 
     [m_delegate loadResource4WithErrorCallback:errorCallback successCallback:successCallback];
 }
 
-void ObjCInspectorNetwork3BackendDispatcher::loadResource5(long callId)
+void ObjCInspectorNetwork3BackendDispatcher::loadResource5(long requestId)
 {
     id errorCallback = ^(NSString *error) {
-        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
+        backendDispatcher()->sendPendingErrors();
     };
 
     id successCallback = ^{
-        backendDispatcher()->sendResponse(callId, InspectorObject::create(), String());
+        backendDispatcher()->sendResponse(requestId, InspectorObject::create());
     };
 
     [m_delegate loadResource5WithErrorCallback:errorCallback successCallback:successCallback];
 }
 
-void ObjCInspectorNetwork3BackendDispatcher::loadResource6(long callId)
+void ObjCInspectorNetwork3BackendDispatcher::loadResource6(long requestId)
 {
     id errorCallback = ^(NSString *error) {
-        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
+        backendDispatcher()->sendPendingErrors();
     };
 
     id successCallback = ^{
-        backendDispatcher()->sendResponse(callId, InspectorObject::create(), String());
+        backendDispatcher()->sendResponse(requestId, InspectorObject::create());
     };
 
     [m_delegate loadResource6WithErrorCallback:errorCallback successCallback:successCallback];
 }
 
-void ObjCInspectorNetwork3BackendDispatcher::loadResource7(long callId)
+void ObjCInspectorNetwork3BackendDispatcher::loadResource7(long requestId)
 {
     id errorCallback = ^(NSString *error) {
-        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
+        backendDispatcher()->sendPendingErrors();
     };
 
     id successCallback = ^{
-        backendDispatcher()->sendResponse(callId, InspectorObject::create(), String());
+        backendDispatcher()->sendResponse(requestId, InspectorObject::create());
     };
 
     [m_delegate loadResource7WithErrorCallback:errorCallback successCallback:successCallback];
index 9d74853..d1f1ff1 100644 (file)
@@ -169,9 +169,9 @@ protected:
 class CommandDomainBackendDispatcher final : public SupplementalBackendDispatcher {
 public:
     static Ref<CommandDomainBackendDispatcher> create(BackendDispatcher*, CommandDomainBackendDispatcherHandler*);
-    virtual void dispatch(long callId, const String& method, Ref<InspectorObject>&& message) override;
+    virtual void dispatch(long requestId, const String& method, Ref<InspectorObject>&& message) override;
 private:
-    void commandWithEnumReturnValue(long callId, const InspectorObject& message);
+    void commandWithEnumReturnValue(long requestId, RefPtr<InspectorObject>&& parameters);
 private:
     CommandDomainBackendDispatcher(BackendDispatcher&, CommandDomainBackendDispatcherHandler*);
     CommandDomainBackendDispatcherHandler* m_agent;
@@ -224,6 +224,7 @@ private:
 
 #include <inspector/InspectorFrontendChannel.h>
 #include <inspector/InspectorValues.h>
+#include <wtf/NeverDestroyed.h>
 #include <wtf/text/CString.h>
 
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
@@ -249,21 +250,24 @@ CommandDomainBackendDispatcher::CommandDomainBackendDispatcher(BackendDispatcher
     m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("CommandDomain"), this);
 }
 
-void CommandDomainBackendDispatcher::dispatch(long callId, const String& method, Ref<InspectorObject>&& message)
+void CommandDomainBackendDispatcher::dispatch(long requestId, const String& method, Ref<InspectorObject>&& message)
 {
     Ref<CommandDomainBackendDispatcher> protect(*this);
 
+    RefPtr<InspectorObject> parameters;
+    message->getObject(ASCIILiteral("params"), parameters);
+
     if (method == "commandWithEnumReturnValue")
-        commandWithEnumReturnValue(callId, message);
+        commandWithEnumReturnValue(requestId, WTF::move(parameters));
     else
-        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::MethodNotFound, makeString('\'', "CommandDomain", '.', method, "' was not found"));
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::MethodNotFound, makeString('\'', "CommandDomain", '.', method, "' was not found"));
 }
 
-void CommandDomainBackendDispatcher::commandWithEnumReturnValue(long callId, const InspectorObject&)
+void CommandDomainBackendDispatcher::commandWithEnumReturnValue(long requestId, RefPtr<InspectorObject>&&)
 {
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
     if (m_alternateDispatcher) {
-        m_alternateDispatcher->commandWithEnumReturnValue(callId);
+        m_alternateDispatcher->commandWithEnumReturnValue(requestId);
         return;
     }
 #endif
@@ -276,7 +280,10 @@ void CommandDomainBackendDispatcher::commandWithEnumReturnValue(long callId, con
     if (!error.length())
         result->setString(ASCIILiteral("returnValue"), Inspector::Protocol::getEnumConstantValue(out_returnValue));
 
-    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+    if (!error.length())
+        m_backendDispatcher->sendResponse(requestId, WTF::move(result));
+    else
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTF::move(error));
 }
 
 } // namespace Inspector
@@ -584,7 +591,7 @@ namespace Inspector {
 class ObjCInspectorCommandDomainBackendDispatcher final : public AlternateCommandDomainBackendDispatcher {
 public:
     ObjCInspectorCommandDomainBackendDispatcher(id<RWIProtocolCommandDomainDomainHandler> handler) { m_delegate = handler; }
-    virtual void commandWithEnumReturnValue(long callId) override;
+    virtual void commandWithEnumReturnValue(long requestId) override;
 private:
     RetainPtr<id<RWIProtocolCommandDomainDomainHandler>> m_delegate;
 };
@@ -777,16 +784,17 @@ namespace Inspector {
 
 
 
-void ObjCInspectorCommandDomainBackendDispatcher::commandWithEnumReturnValue(long callId)
+void ObjCInspectorCommandDomainBackendDispatcher::commandWithEnumReturnValue(long requestId)
 {
     id errorCallback = ^(NSString *error) {
-        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
+        backendDispatcher()->sendPendingErrors();
     };
 
     id successCallback = ^(RWIProtocolCommandDomainCommandWithEnumReturnValueReturnValue returnValue) {
         Ref<InspectorObject> resultObject = InspectorObject::create();
         resultObject->setString(ASCIILiteral("returnValue"), toProtocolString(returnValue));
-        backendDispatcher()->sendResponse(callId, WTF::move(resultObject), String());
+        backendDispatcher()->sendResponse(requestId, WTF::move(resultObject));
     };
 
     [m_delegate commandWithEnumReturnValueWithErrorCallback:errorCallback successCallback:successCallback];
index 4b622d9..ad526d3 100644 (file)
@@ -180,6 +180,7 @@ typedef String ErrorString;
 
 #include <inspector/InspectorFrontendChannel.h>
 #include <inspector/InspectorValues.h>
+#include <wtf/NeverDestroyed.h>
 #include <wtf/text/CString.h>
 
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
index bb8d29d..87005f5 100644 (file)
@@ -165,9 +165,9 @@ protected:
 class Network1BackendDispatcher final : public SupplementalBackendDispatcher {
 public:
     static Ref<Network1BackendDispatcher> create(BackendDispatcher*, Network1BackendDispatcherHandler*);
-    virtual void dispatch(long callId, const String& method, Ref<InspectorObject>&& message) override;
+    virtual void dispatch(long requestId, const String& method, Ref<InspectorObject>&& message) override;
 private:
-    void loadResource(long callId, const InspectorObject& message);
+    void loadResource(long requestId, RefPtr<InspectorObject>&& parameters);
 private:
     Network1BackendDispatcher(BackendDispatcher&, Network1BackendDispatcherHandler*);
     Network1BackendDispatcherHandler* m_agent;
@@ -221,6 +221,7 @@ private:
 
 #include <inspector/InspectorFrontendChannel.h>
 #include <inspector/InspectorValues.h>
+#include <wtf/NeverDestroyed.h>
 #include <wtf/text/CString.h>
 
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
@@ -249,21 +250,24 @@ Network1BackendDispatcher::Network1BackendDispatcher(BackendDispatcher& backendD
     m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("Network1"), this);
 }
 
-void Network1BackendDispatcher::dispatch(long callId, const String& method, Ref<InspectorObject>&& message)
+void Network1BackendDispatcher::dispatch(long requestId, const String& method, Ref<InspectorObject>&& message)
 {
     Ref<Network1BackendDispatcher> protect(*this);
 
+    RefPtr<InspectorObject> parameters;
+    message->getObject(ASCIILiteral("params"), parameters);
+
     if (method == "loadResource")
-        loadResource(callId, message);
+        loadResource(requestId, WTF::move(parameters));
     else
-        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::MethodNotFound, makeString('\'', "Network1", '.', method, "' was not found"));
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::MethodNotFound, makeString('\'', "Network1", '.', method, "' was not found"));
 }
 
-void Network1BackendDispatcher::loadResource(long callId, const InspectorObject&)
+void Network1BackendDispatcher::loadResource(long requestId, RefPtr<InspectorObject>&&)
 {
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
     if (m_alternateDispatcher) {
-        m_alternateDispatcher->loadResource(callId);
+        m_alternateDispatcher->loadResource(requestId);
         return;
     }
 #endif
@@ -272,7 +276,10 @@ void Network1BackendDispatcher::loadResource(long callId, const InspectorObject&
     Ref<InspectorObject> result = InspectorObject::create();
     m_agent->loadResource(error);
 
-    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+    if (!error.length())
+        m_backendDispatcher->sendResponse(requestId, WTF::move(result));
+    else
+        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTF::move(error));
 }
 #endif // PLATFORM(WEB_COMMANDS)
 
@@ -627,7 +634,7 @@ namespace Inspector {
 class ObjCInspectorNetwork1BackendDispatcher final : public AlternateNetwork1BackendDispatcher {
 public:
     ObjCInspectorNetwork1BackendDispatcher(id<RWIProtocolNetwork1DomainHandler> handler) { m_delegate = handler; }
-    virtual void loadResource(long callId) override;
+    virtual void loadResource(long requestId) override;
 private:
     RetainPtr<id<RWIProtocolNetwork1DomainHandler>> m_delegate;
 };
@@ -822,14 +829,15 @@ __attribute__((visibility ("default")))
 namespace Inspector {
 
 #if PLATFORM(WEB_COMMANDS)
-void ObjCInspectorNetwork1BackendDispatcher::loadResource(long callId)
+void ObjCInspectorNetwork1BackendDispatcher::loadResource(long requestId)
 {
     id errorCallback = ^(NSString *error) {
-        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
+        backendDispatcher()->sendPendingErrors();
     };
 
     id successCallback = ^{
-        backendDispatcher()->sendResponse(callId, InspectorObject::create(), String());
+        backendDispatcher()->sendResponse(requestId, InspectorObject::create());
     };
 
     [m_delegate loadResourceWithErrorCallback:errorCallback successCallback:successCallback];
index c272f72..30cce18 100644 (file)
@@ -174,6 +174,7 @@ typedef String ErrorString;
 
 #include <inspector/InspectorFrontendChannel.h>
 #include <inspector/InspectorValues.h>
+#include <wtf/NeverDestroyed.h>
 #include <wtf/text/CString.h>
 
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
index a8186e0..28e1456 100644 (file)
@@ -174,6 +174,7 @@ typedef String ErrorString;
 
 #include <inspector/InspectorFrontendChannel.h>
 #include <inspector/InspectorValues.h>
+#include <wtf/NeverDestroyed.h>
 #include <wtf/text/CString.h>
 
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
index 53b3f22..8bbfc29 100644 (file)
@@ -174,6 +174,7 @@ typedef String ErrorString;
 
 #include <inspector/InspectorFrontendChannel.h>
 #include <inspector/InspectorValues.h>
+#include <wtf/NeverDestroyed.h>
 #include <wtf/text/CString.h>
 
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
index 7e9ef1e..d0f4af1 100644 (file)
@@ -177,6 +177,7 @@ typedef String ErrorString;
 
 #include <inspector/InspectorFrontendChannel.h>
 #include <inspector/InspectorValues.h>
+#include <wtf/NeverDestroyed.h>
 #include <wtf/text/CString.h>
 
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
index 6d63dd5..34c285c 100644 (file)
@@ -178,6 +178,7 @@ typedef String ErrorString;
 
 #include <inspector/InspectorFrontendChannel.h>
 #include <inspector/InspectorValues.h>
+#include <wtf/NeverDestroyed.h>
 #include <wtf/text/CString.h>
 
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
index 6e94941..60db5ec 100644 (file)
@@ -174,6 +174,7 @@ typedef String ErrorString;
 
 #include <inspector/InspectorFrontendChannel.h>
 #include <inspector/InspectorValues.h>
+#include <wtf/NeverDestroyed.h>
 #include <wtf/text/CString.h>
 
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
index 9eb1d40..3c176f5 100644 (file)
@@ -178,6 +178,7 @@ typedef String ErrorString;
 
 #include <inspector/InspectorFrontendChannel.h>
 #include <inspector/InspectorValues.h>
+#include <wtf/NeverDestroyed.h>
 #include <wtf/text/CString.h>
 
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
index 41fe7d0..77eb3a0 100644 (file)
@@ -1,3 +1,12 @@
+2015-08-25  Brian Burg  <bburg@apple.com>
+
+        Web Inspector: no need to allocate protocolErrors array for every dispatched backend command
+        https://bugs.webkit.org/show_bug.cgi?id=146466
+
+        Reviewed by Joseph Pecoraro.
+
+        * UserInterface/TestStub.html: Fix a typo, this property exists on ProtocolTest.
+
 2015-08-26  Matt Baker  <mattbaker@apple.com>
 
         Web Inspector: Rendering Frames legend item checkbox colors are too light
index 9a452c5..7b5204d 100644 (file)
@@ -47,7 +47,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
         ProtocolTest.dumpActivityToSystemConsole = false;
 
         // Best used in combination with dumpActivityToSystemConsole.
-        InspectorProtocol.dumpInspectorProtocolMessages = false;
+        ProtocolTest.dumpInspectorProtocolMessages = false;
     </script>
 </head>
 </html>