Title: [238507] trunk/Source/WebKit
Revision
238507
Author
[email protected]
Date
2018-11-26 11:55:30 -0800 (Mon, 26 Nov 2018)

Log Message

CompletionHandler-based async IPC messages only work when the completion handler takes a single argument
https://bugs.webkit.org/show_bug.cgi?id=191965

Reviewed by Tim Horton.

Teach `messages.py` to handle the case where an async IPC completion handler takes no arguments, or takes more
than a single argument. Currently, the generated code attempts to wrap all arguments in a `WTFMove(*~)`, but
this either results in `WTFMove(*)` in the case where there are no arguments, or `WTFMove(*foo, *bar, *baz)` in
the case where there are several arguments. Both of these results fail to compile.

Instead, emit `completionHandler()` when there are no arguments, and
`completionHandler(WTFMove(*foo), WTFMove(*bar), WTFMove(*baz))` when there are multiple arguments.

Tests:  TestAsyncMessageWithNoArguments
        TestAsyncMessageWithMultipleArguments

* Scripts/webkit/MessageReceiverSuperclass-expected.cpp:
(Messages::WebPage::TestAsyncMessageWithNoArguments::callReply):
(Messages::WebPage::TestAsyncMessageWithNoArguments::cancelReply):
(Messages::WebPage::TestAsyncMessageWithNoArguments::send):
(Messages::WebPage::TestAsyncMessageWithMultipleArguments::callReply):
(Messages::WebPage::TestAsyncMessageWithMultipleArguments::cancelReply):
(Messages::WebPage::TestAsyncMessageWithMultipleArguments::send):
(WebKit::WebPage::didReceiveMessage):
* Scripts/webkit/MessagesSuperclass-expected.h:
(Messages::WebPage::TestAsyncMessageWithNoArguments::receiverName):
(Messages::WebPage::TestAsyncMessageWithNoArguments::name):
(Messages::WebPage::TestAsyncMessageWithNoArguments::asyncMessageReplyName):
(Messages::WebPage::TestAsyncMessageWithNoArguments::arguments const):
(Messages::WebPage::TestAsyncMessageWithMultipleArguments::receiverName):
(Messages::WebPage::TestAsyncMessageWithMultipleArguments::name):
(Messages::WebPage::TestAsyncMessageWithMultipleArguments::asyncMessageReplyName):
(Messages::WebPage::TestAsyncMessageWithMultipleArguments::arguments const):
* Scripts/webkit/messages.py:
* Scripts/webkit/messages_unittest.py:

Add new `messages.py` unit tests to cover these cases.

* Scripts/webkit/test-superclass-messages.in:

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (238506 => 238507)


--- trunk/Source/WebKit/ChangeLog	2018-11-26 19:51:53 UTC (rev 238506)
+++ trunk/Source/WebKit/ChangeLog	2018-11-26 19:55:30 UTC (rev 238507)
@@ -1,3 +1,45 @@
+2018-11-26  Wenson Hsieh  <[email protected]>
+
+        CompletionHandler-based async IPC messages only work when the completion handler takes a single argument
+        https://bugs.webkit.org/show_bug.cgi?id=191965
+
+        Reviewed by Tim Horton.
+
+        Teach `messages.py` to handle the case where an async IPC completion handler takes no arguments, or takes more
+        than a single argument. Currently, the generated code attempts to wrap all arguments in a `WTFMove(*~)`, but
+        this either results in `WTFMove(*)` in the case where there are no arguments, or `WTFMove(*foo, *bar, *baz)` in
+        the case where there are several arguments. Both of these results fail to compile.
+
+        Instead, emit `completionHandler()` when there are no arguments, and
+        `completionHandler(WTFMove(*foo), WTFMove(*bar), WTFMove(*baz))` when there are multiple arguments.
+
+        Tests:  TestAsyncMessageWithNoArguments
+                TestAsyncMessageWithMultipleArguments
+
+        * Scripts/webkit/MessageReceiverSuperclass-expected.cpp:
+        (Messages::WebPage::TestAsyncMessageWithNoArguments::callReply):
+        (Messages::WebPage::TestAsyncMessageWithNoArguments::cancelReply):
+        (Messages::WebPage::TestAsyncMessageWithNoArguments::send):
+        (Messages::WebPage::TestAsyncMessageWithMultipleArguments::callReply):
+        (Messages::WebPage::TestAsyncMessageWithMultipleArguments::cancelReply):
+        (Messages::WebPage::TestAsyncMessageWithMultipleArguments::send):
+        (WebKit::WebPage::didReceiveMessage):
+        * Scripts/webkit/MessagesSuperclass-expected.h:
+        (Messages::WebPage::TestAsyncMessageWithNoArguments::receiverName):
+        (Messages::WebPage::TestAsyncMessageWithNoArguments::name):
+        (Messages::WebPage::TestAsyncMessageWithNoArguments::asyncMessageReplyName):
+        (Messages::WebPage::TestAsyncMessageWithNoArguments::arguments const):
+        (Messages::WebPage::TestAsyncMessageWithMultipleArguments::receiverName):
+        (Messages::WebPage::TestAsyncMessageWithMultipleArguments::name):
+        (Messages::WebPage::TestAsyncMessageWithMultipleArguments::asyncMessageReplyName):
+        (Messages::WebPage::TestAsyncMessageWithMultipleArguments::arguments const):
+        * Scripts/webkit/messages.py:
+        * Scripts/webkit/messages_unittest.py:
+
+        Add new `messages.py` unit tests to cover these cases.
+
+        * Scripts/webkit/test-superclass-messages.in:
+
 2018-11-26  Jeremy Jones  <[email protected]>
 
         Use Full Screen consistently in localizable strings.

Modified: trunk/Source/WebKit/Scripts/webkit/MessageReceiverSuperclass-expected.cpp (238506 => 238507)


--- trunk/Source/WebKit/Scripts/webkit/MessageReceiverSuperclass-expected.cpp	2018-11-26 19:51:53 UTC (rev 238506)
+++ trunk/Source/WebKit/Scripts/webkit/MessageReceiverSuperclass-expected.cpp	2018-11-26 19:55:30 UTC (rev 238507)
@@ -67,6 +67,58 @@
 
 #endif
 
+#if ENABLE(TEST_FEATURE)
+
+void TestAsyncMessageWithNoArguments::callReply(IPC::Decoder& decoder, CompletionHandler<void()>&& completionHandler)
+{
+    completionHandler();
+}
+
+void TestAsyncMessageWithNoArguments::cancelReply(CompletionHandler<void()>&& completionHandler)
+{
+    completionHandler();
+}
+
+void TestAsyncMessageWithNoArguments::send(std::unique_ptr<IPC::Encoder>&& encoder, IPC::Connection& connection)
+{
+    connection.sendSyncReply(WTFMove(encoder));
+}
+
+#endif
+
+#if ENABLE(TEST_FEATURE)
+
+void TestAsyncMessageWithMultipleArguments::callReply(IPC::Decoder& decoder, CompletionHandler<void(bool&&, uint64_t&&)>&& completionHandler)
+{
+    std::optional<bool> flag;
+    decoder >> flag;
+    if (!flag) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+    std::optional<uint64_t> value;
+    decoder >> value;
+    if (!value) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+    completionHandler(WTFMove(*flag), WTFMove(*value));
+}
+
+void TestAsyncMessageWithMultipleArguments::cancelReply(CompletionHandler<void(bool&&, uint64_t&&)>&& completionHandler)
+{
+    completionHandler({ }, { });
+}
+
+void TestAsyncMessageWithMultipleArguments::send(std::unique_ptr<IPC::Encoder>&& encoder, IPC::Connection& connection, bool flag, uint64_t value)
+{
+    *encoder << flag;
+    *encoder << value;
+    connection.sendSyncReply(WTFMove(encoder));
+}
+
+#endif
+
 void TestDelayedMessage::send(std::unique_ptr<IPC::Encoder>&& encoder, IPC::Connection& connection, const std::optional<WebKit::TestClassName>& optionalReply)
 {
     *encoder << optionalReply;
@@ -91,6 +143,18 @@
         return;
     }
 #endif
+#if ENABLE(TEST_FEATURE)
+    if (decoder.messageName() == Messages::WebPage::TestAsyncMessageWithNoArguments::name()) {
+        IPC::handleMessageAsync<Messages::WebPage::TestAsyncMessageWithNoArguments>(connection, decoder, this, &WebPage::testAsyncMessageWithNoArguments);
+        return;
+    }
+#endif
+#if ENABLE(TEST_FEATURE)
+    if (decoder.messageName() == Messages::WebPage::TestAsyncMessageWithMultipleArguments::name()) {
+        IPC::handleMessageAsync<Messages::WebPage::TestAsyncMessageWithMultipleArguments>(connection, decoder, this, &WebPage::testAsyncMessageWithMultipleArguments);
+        return;
+    }
+#endif
     WebPageBase::didReceiveMessage(connection, decoder);
 }
 

Modified: trunk/Source/WebKit/Scripts/webkit/MessagesSuperclass-expected.h (238506 => 238507)


--- trunk/Source/WebKit/Scripts/webkit/MessagesSuperclass-expected.h	2018-11-26 19:51:53 UTC (rev 238506)
+++ trunk/Source/WebKit/Scripts/webkit/MessagesSuperclass-expected.h	2018-11-26 19:55:30 UTC (rev 238507)
@@ -99,6 +99,56 @@
 };
 #endif
 
+#if ENABLE(TEST_FEATURE)
+class TestAsyncMessageWithNoArguments {
+public:
+    typedef std::tuple<> Arguments;
+
+    static IPC::StringReference receiverName() { return messageReceiverName(); }
+    static IPC::StringReference name() { return IPC::StringReference("TestAsyncMessageWithNoArguments"); }
+    static const bool isSync = false;
+
+    static void callReply(IPC::Decoder&, CompletionHandler<void()>&&);
+    static void cancelReply(CompletionHandler<void()>&&);
+    static IPC::StringReference asyncMessageReplyName() { return { "TestAsyncMessageWithNoArgumentsReply" }; }
+    using AsyncReply = CompletionHandler<void()>;
+    static void send(std::unique_ptr<IPC::Encoder>&&, IPC::Connection&);
+    typedef std::tuple<> Reply;
+    const Arguments& arguments() const
+    {
+        return m_arguments;
+    }
+
+private:
+    Arguments m_arguments;
+};
+#endif
+
+#if ENABLE(TEST_FEATURE)
+class TestAsyncMessageWithMultipleArguments {
+public:
+    typedef std::tuple<> Arguments;
+
+    static IPC::StringReference receiverName() { return messageReceiverName(); }
+    static IPC::StringReference name() { return IPC::StringReference("TestAsyncMessageWithMultipleArguments"); }
+    static const bool isSync = false;
+
+    static void callReply(IPC::Decoder&, CompletionHandler<void(bool&&, uint64_t&&)>&&);
+    static void cancelReply(CompletionHandler<void(bool&&, uint64_t&&)>&&);
+    static IPC::StringReference asyncMessageReplyName() { return { "TestAsyncMessageWithMultipleArgumentsReply" }; }
+    using AsyncReply = CompletionHandler<void(bool flag, uint64_t value)>;
+    static void send(std::unique_ptr<IPC::Encoder>&&, IPC::Connection&, bool flag, uint64_t value);
+    typedef std::tuple<bool&, uint64_t&> Reply;
+    const Arguments& arguments() const
+    {
+        return m_arguments;
+    }
+
+private:
+    Arguments m_arguments;
+};
+#endif
+
 class TestSyncMessage {
 public:
     typedef std::tuple<uint32_t> Arguments;

Modified: trunk/Source/WebKit/Scripts/webkit/messages.py (238506 => 238507)


--- trunk/Source/WebKit/Scripts/webkit/messages.py	2018-11-26 19:51:53 UTC (rev 238506)
+++ trunk/Source/WebKit/Scripts/webkit/messages.py	2018-11-26 19:55:30 UTC (rev 238507)
@@ -566,7 +566,10 @@
                     result.append('    std::optional<%s> %s;\n' % (x.type, x.name))
                     result.append('    decoder >> %s;\n' % x.name)
                     result.append('    if (!%s) {\n        ASSERT_NOT_REACHED();\n        return;\n    }\n' % x.name)
-                result.append('    completionHandler(WTFMove(*%s));\n}\n\n' % (', *'.join(x.name for x in message.reply_parameters)))
+                result.append('    completionHandler(')
+                if len(message.reply_parameters):
+                    result.append('WTFMove(*%s)' % ('), WTFMove(*'.join(x.name for x in message.reply_parameters)))
+                result.append(');\n}\n\n')
                 result.append('void %s::cancelReply(CompletionHandler<void(%s)>&& completionHandler)\n{\n    completionHandler(' % move_parameters)
                 result.append(', '.join(['{ }' for x in message.reply_parameters]))
                 result.append(');\n}\n\n')

Modified: trunk/Source/WebKit/Scripts/webkit/messages_unittest.py (238506 => 238507)


--- trunk/Source/WebKit/Scripts/webkit/messages_unittest.py	2018-11-26 19:51:53 UTC (rev 238506)
+++ trunk/Source/WebKit/Scripts/webkit/messages_unittest.py	2018-11-26 19:55:30 UTC (rev 238507)
@@ -255,6 +255,21 @@
             'conditions': ('ENABLE(TEST_FEATURE)'),
         },
         {
+            'name': 'TestAsyncMessageWithNoArguments',
+            'parameters': (),
+            'reply_parameters': (),
+            'conditions': ('ENABLE(TEST_FEATURE)'),
+        },
+        {
+            'name': 'TestAsyncMessageWithMultipleArguments',
+            'parameters': (),
+            'reply_parameters': (
+                ('bool', 'flag'),
+                ('uint64_t', 'value'),
+            ),
+            'conditions': ('ENABLE(TEST_FEATURE)'),
+        },
+        {
             'name': 'TestSyncMessage',
             'parameters': (
                 ('uint32_t', 'param'),

Modified: trunk/Source/WebKit/Scripts/webkit/test-superclass-messages.in (238506 => 238507)


--- trunk/Source/WebKit/Scripts/webkit/test-superclass-messages.in	2018-11-26 19:51:53 UTC (rev 238506)
+++ trunk/Source/WebKit/Scripts/webkit/test-superclass-messages.in	2018-11-26 19:55:30 UTC (rev 238507)
@@ -24,6 +24,8 @@
     LoadURL(String url)
 #if ENABLE(TEST_FEATURE)
     TestAsyncMessage(enum:bool WebKit::TestTwoStateEnum twoStateEnum) -> (uint64_t result) Async
+    TestAsyncMessageWithNoArguments() -> () Async
+    TestAsyncMessageWithMultipleArguments() -> (bool flag, uint64_t value) Async
 #endif
     TestSyncMessage(uint32_t param) -> (uint8_t reply) Sync
     TestDelayedMessage(bool value) -> (std::optional<WebKit::TestClassName> optionalReply) Delayed
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to