- 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