Changeset 289524 in webkit


Ignore:
Timestamp:
Feb 10, 2022, 1:27:09 AM (4 years ago)
Author:
commit-queue@webkit.org
Message:

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

Patch by Kimmo Kinnunen <kkinnunen@apple.com> 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):

Location:
trunk/Source/WebKit
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r289519 r289524  
     12022-02-10  Kimmo Kinnunen  <kkinnunen@apple.com>
     2
     3        Non-default constructible types cannot be decoded with IPC::Decoder
     4        https://bugs.webkit.org/show_bug.cgi?id=236246
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Add yet another decode function: std::optional<T> Decoder::decode<T>();
     9
     10        Consider the pattern:
     11          std::optional<T> t;
     12          decoder >> t;
     13          if (!t)
     14            ....
     15
     16        The above neccessitates default construction of T, since it contains
     17          std::optional<T> t;
     18          t =  ...; assignment. This assignment cannot be elided.
     19        Better pattern is:
     20          auto t = decoder.decode<T>();
     21
     22        This is significant with for types with const members:
     23          struct T {
     24              const uint64_t version;
     25          };
     26
     27        * Platform/IPC/Decoder.h:
     28        (IPC::Decoder::decode):
     29        (IPC::Decoder::operator>>):
     30        * Platform/IPC/HandleMessage.h:
     31        (IPC::handleMessage):
     32        (IPC::handleMessageWantsConnection):
     33        (IPC::handleMessageSynchronous):
     34        (IPC::handleMessageSynchronousWantsConnection):
     35        (IPC::handleMessageAsync):
     36        (IPC::handleMessageAsyncWantsConnection):
     37
    1382022-02-09  Ross Kirsling  <ross.kirsling@sony.com>
    239
  • trunk/Source/WebKit/Platform/IPC/Decoder.h

    r288354 r289524  
    9898            }
    9999        } else {
    100             std::optional<T> optional;
    101             *this >> optional;
     100            std::optional<T> optional { decode<T>() };
    102101            if (UNLIKELY(!optional)) {
    103102                markInvalid();
     
    112111    Decoder& operator>>(std::optional<T>& t)
    113112    {
     113        t = decode<T>();
     114        return *this;
     115    }
     116
     117    // The preferred decode() function. Can decode T which is not default constructible when T
     118    // has a  modern decoder, e.g decoding function that returns std::optional.
     119    template<typename T>
     120    std::optional<T> decode()
     121    {
    114122        using Impl = ArgumentCoder<std::remove_const_t<std::remove_reference_t<T>>, void>;
    115123        if constexpr(HasModernDecoder<T, Impl>::value) {
    116             t = Impl::decode(*this);
     124            std::optional<T> t { Impl::decode(*this) };
    117125            if (UNLIKELY(!t))
    118126                markInvalid();
     127            return t;
    119128        } else {
    120             T v;
    121             if (LIKELY(Impl::decode(*this, v)))
    122                 t = WTFMove(v);
    123             else
    124                 markInvalid();
     129            std::optional<T> t { T { } };
     130            if (LIKELY(Impl::decode(*this, *t)))
     131                return t;
     132            markInvalid();
     133            return std::nullopt;
    125134        }
    126         return *this;
    127135    }
    128136
  • trunk/Source/WebKit/Platform/IPC/HandleMessage.h

    r287808 r289524  
    189189void handleMessage(Connection& connection, Decoder& decoder, C* object, MF function)
    190190{
    191     std::optional<typename CodingType<typename T::Arguments>::Type> arguments;
    192     decoder >> arguments;
     191    auto arguments = decoder.decode<typename CodingType<typename T::Arguments>::Type>();
    193192    if (UNLIKELY(!arguments))
    194193        return;
     
    201200void handleMessageWantsConnection(Connection& connection, Decoder& decoder, C* object, MF function)
    202201{
    203     std::optional<typename CodingType<typename T::Arguments>::Type> arguments;
    204     decoder >> arguments;
     202    auto arguments = decoder.decode<typename CodingType<typename T::Arguments>::Type>();
    205203    if (UNLIKELY(!arguments))
    206204        return;
     
    213211bool handleMessageSynchronous(Connection& connection, Decoder& decoder, UniqueRef<Encoder>& replyEncoder, C* object, MF function)
    214212{
    215     std::optional<typename CodingType<typename T::Arguments>::Type> arguments;
    216     decoder >> arguments;
     213    auto arguments = decoder.decode<typename CodingType<typename T::Arguments>::Type>();
    217214    if (UNLIKELY(!arguments))
    218215        return false;
     
    230227bool handleMessageSynchronousWantsConnection(Connection& connection, Decoder& decoder, UniqueRef<Encoder>& replyEncoder, C* object, MF function)
    231228{
    232     std::optional<typename CodingType<typename T::Arguments>::Type> arguments;
    233     decoder >> arguments;
     229    auto arguments = decoder.decode<typename CodingType<typename T::Arguments>::Type>();
    234230    if (UNLIKELY(!arguments))
    235231        return false;
     
    251247        return;
    252248
    253     std::optional<typename CodingType<typename T::Arguments>::Type> arguments;
    254     decoder >> arguments;
     249    auto arguments = decoder.decode<typename CodingType<typename T::Arguments>::Type>();
    255250    if (UNLIKELY(!arguments))
    256251        return;
     
    267262void handleMessageAsync(Connection& connection, Decoder& decoder, C* object, MF function)
    268263{
    269     std::optional<uint64_t> listenerID;
    270     decoder >> listenerID;
    271     if (!listenerID)
    272         return;
    273 
    274     std::optional<typename CodingType<typename T::Arguments>::Type> arguments;
    275     decoder >> arguments;
     264    auto listenerID = decoder.decode<uint64_t>();
     265    if (UNLIKELY(!listenerID))
     266        return;
     267
     268    auto arguments = decoder.decode<typename CodingType<typename T::Arguments>::Type>();
    276269    if (UNLIKELY(!arguments))
    277270        return;
     
    289282void handleMessageAsyncWantsConnection(Connection& connection, Decoder& decoder, C* object, MF function)
    290283{
    291     std::optional<uint64_t> listenerID;
    292     decoder >> listenerID;
    293     if (!listenerID)
    294         return;
    295 
    296     std::optional<typename CodingType<typename T::Arguments>::Type> arguments;
    297     decoder >> arguments;
     284    auto listenerID = decoder.decode<uint64_t>();
     285    if (UNLIKELY(!listenerID))
     286        return;
     287
     288    auto arguments = decoder.decode<typename CodingType<typename T::Arguments>::Type>();
    298289    if (UNLIKELY(!arguments))
    299290        return;
Note: See TracChangeset for help on using the changeset viewer.