Title: [289524] trunk/Source/WebKit
Revision
289524
Author
[email protected]
Date
2022-02-10 01:27:09 -0800 (Thu, 10 Feb 2022)

Log Message

Non-default constructible types cannot be decoded with IPC::Decoder
https://bugs.webkit.org/show_bug.cgi?id=236246

Patch by Kimmo Kinnunen <[email protected]> on 2022-02-10
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):

Modified Paths

Diff

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;
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to