Modified: trunk/Source/WebKit/ChangeLog (289523 => 289524)
--- trunk/Source/WebKit/ChangeLog 2022-02-10 09:07:04 UTC (rev 289523)
+++ trunk/Source/WebKit/ChangeLog 2022-02-10 09:27:09 UTC (rev 289524)
@@ -1,3 +1,40 @@
+2022-02-10 Kimmo Kinnunen <[email protected]>
+
+ Non-default constructible types cannot be decoded with IPC::Decoder
+ https://bugs.webkit.org/show_bug.cgi?id=236246
+
+ Reviewed by Antti Koivisto.
+
+ Add yet another decode function: std::optional<T> Decoder::decode<T>();
+
+ Consider the pattern:
+ std::optional<T> t;
+ decoder >> t;
+ if (!t)
+ ....
+
+ The above neccessitates default construction of T, since it contains
+ std::optional<T> t;
+ t = ...; assignment. This assignment cannot be elided.
+ Better pattern is:
+ auto t = decoder.decode<T>();
+
+ This is significant with for types with const members:
+ struct T {
+ const uint64_t version;
+ };
+
+ * Platform/IPC/Decoder.h:
+ (IPC::Decoder::decode):
+ (IPC::Decoder::operator>>):
+ * Platform/IPC/HandleMessage.h:
+ (IPC::handleMessage):
+ (IPC::handleMessageWantsConnection):
+ (IPC::handleMessageSynchronous):
+ (IPC::handleMessageSynchronousWantsConnection):
+ (IPC::handleMessageAsync):
+ (IPC::handleMessageAsyncWantsConnection):
+
2022-02-09 Ross Kirsling <[email protected]>
SharedMemoryUnix should use SHM_ANON when available
Modified: trunk/Source/WebKit/Platform/IPC/Decoder.h (289523 => 289524)
--- trunk/Source/WebKit/Platform/IPC/Decoder.h 2022-02-10 09:07:04 UTC (rev 289523)
+++ trunk/Source/WebKit/Platform/IPC/Decoder.h 2022-02-10 09:27:09 UTC (rev 289524)
@@ -97,8 +97,7 @@
return false;
}
} else {
- std::optional<T> optional;
- *this >> optional;
+ std::optional<T> optional { decode<T>() };
if (UNLIKELY(!optional)) {
markInvalid();
return false;
@@ -111,19 +110,28 @@
template<typename T>
Decoder& operator>>(std::optional<T>& t)
{
+ t = decode<T>();
+ return *this;
+ }
+
+ // The preferred decode() function. Can decode T which is not default constructible when T
+ // has a modern decoder, e.g decoding function that returns std::optional.
+ template<typename T>
+ std::optional<T> decode()
+ {
using Impl = ArgumentCoder<std::remove_const_t<std::remove_reference_t<T>>, void>;
if constexpr(HasModernDecoder<T, Impl>::value) {
- t = Impl::decode(*this);
+ std::optional<T> t { Impl::decode(*this) };
if (UNLIKELY(!t))
markInvalid();
+ return t;
} else {
- T v;
- if (LIKELY(Impl::decode(*this, v)))
- t = WTFMove(v);
- else
- markInvalid();
+ std::optional<T> t { T { } };
+ if (LIKELY(Impl::decode(*this, *t)))
+ return t;
+ markInvalid();
+ return std::nullopt;
}
- return *this;
}
template<typename T>
Modified: trunk/Source/WebKit/Platform/IPC/HandleMessage.h (289523 => 289524)
--- trunk/Source/WebKit/Platform/IPC/HandleMessage.h 2022-02-10 09:07:04 UTC (rev 289523)
+++ trunk/Source/WebKit/Platform/IPC/HandleMessage.h 2022-02-10 09:27:09 UTC (rev 289524)
@@ -188,8 +188,7 @@
template<typename T, typename C, typename MF>
void handleMessage(Connection& connection, Decoder& decoder, C* object, MF function)
{
- std::optional<typename CodingType<typename T::Arguments>::Type> arguments;
- decoder >> arguments;
+ auto arguments = decoder.decode<typename CodingType<typename T::Arguments>::Type>();
if (UNLIKELY(!arguments))
return;
@@ -200,8 +199,7 @@
template<typename T, typename C, typename MF>
void handleMessageWantsConnection(Connection& connection, Decoder& decoder, C* object, MF function)
{
- std::optional<typename CodingType<typename T::Arguments>::Type> arguments;
- decoder >> arguments;
+ auto arguments = decoder.decode<typename CodingType<typename T::Arguments>::Type>();
if (UNLIKELY(!arguments))
return;
@@ -212,8 +210,7 @@
template<typename T, typename C, typename MF>
bool handleMessageSynchronous(Connection& connection, Decoder& decoder, UniqueRef<Encoder>& replyEncoder, C* object, MF function)
{
- std::optional<typename CodingType<typename T::Arguments>::Type> arguments;
- decoder >> arguments;
+ auto arguments = decoder.decode<typename CodingType<typename T::Arguments>::Type>();
if (UNLIKELY(!arguments))
return false;
@@ -229,8 +226,7 @@
template<typename T, typename C, typename MF>
bool handleMessageSynchronousWantsConnection(Connection& connection, Decoder& decoder, UniqueRef<Encoder>& replyEncoder, C* object, MF function)
{
- std::optional<typename CodingType<typename T::Arguments>::Type> arguments;
- decoder >> arguments;
+ auto arguments = decoder.decode<typename CodingType<typename T::Arguments>::Type>();
if (UNLIKELY(!arguments))
return false;
@@ -250,8 +246,7 @@
if (UNLIKELY(!decoder.decode(syncRequestID)))
return;
- std::optional<typename CodingType<typename T::Arguments>::Type> arguments;
- decoder >> arguments;
+ auto arguments = decoder.decode<typename CodingType<typename T::Arguments>::Type>();
if (UNLIKELY(!arguments))
return;
@@ -266,13 +261,11 @@
template<typename T, typename C, typename MF>
void handleMessageAsync(Connection& connection, Decoder& decoder, C* object, MF function)
{
- std::optional<uint64_t> listenerID;
- decoder >> listenerID;
- if (!listenerID)
+ auto listenerID = decoder.decode<uint64_t>();
+ if (UNLIKELY(!listenerID))
return;
- std::optional<typename CodingType<typename T::Arguments>::Type> arguments;
- decoder >> arguments;
+ auto arguments = decoder.decode<typename CodingType<typename T::Arguments>::Type>();
if (UNLIKELY(!arguments))
return;
@@ -288,13 +281,11 @@
template<typename T, typename C, typename MF>
void handleMessageAsyncWantsConnection(Connection& connection, Decoder& decoder, C* object, MF function)
{
- std::optional<uint64_t> listenerID;
- decoder >> listenerID;
- if (!listenerID)
+ auto listenerID = decoder.decode<uint64_t>();
+ if (UNLIKELY(!listenerID))
return;
- std::optional<typename CodingType<typename T::Arguments>::Type> arguments;
- decoder >> arguments;
+ auto arguments = decoder.decode<typename CodingType<typename T::Arguments>::Type>();
if (UNLIKELY(!arguments))
return;