Bug 207497

Summary: PersistentCoders should use modern decoding syntax
Product: WebKit Reporter: Alex Christensen <achristensen>
Component: Web Template FrameworkAssignee: Alex Christensen <achristensen>
Status: RESOLVED FIXED    
Severity: Normal CC: benjamin, berto, cdumez, cgarcia, cmarcelo, darin, dbates, ddkilzer, don.olmstead, ews-watchlist, galpeter, gustavo, hi, Hironori.Fujii, japhet, joepeck, mcatanzaro, mkwst, ross.kirsling, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: Unspecified   
OS: Unspecified   
Attachments:
Description Flags
patch
none
sub-patch for WinCairo
none
Patch for soup
none
Patch
none
Patch
none
Patch
none
Patch
none
Patch none

Description Alex Christensen 2020-02-10 13:16:35 PST
This paves the way for more serialized types that do not have a default constructor.
Comment 1 Alex Christensen 2020-02-10 13:18:45 PST
Created attachment 390285 [details]
patch
Comment 2 Alex Christensen 2020-02-10 14:13:58 PST
Could someone who works on linux get the linux build working with this change?
Comment 3 Ross Kirsling 2020-02-10 16:36:37 PST
Created attachment 390312 [details]
sub-patch for WinCairo

Here's a diff for making WinCairo green.

One question that arose while doing this:
Is it okay that we don't write WTF::nullopt when we fail to decode?
Comment 4 Alex Christensen 2020-02-10 16:37:42 PST
What do you mean?  We usually try to use WTF::nullopt instead of { } because some people think { } is unclear.
Comment 5 Ross Kirsling 2020-02-10 16:40:08 PST
(In reply to Alex Christensen from comment #4)
> What do you mean?  We usually try to use WTF::nullopt instead of { } because
> some people think { } is unclear.

Oh sorry, too terse. I meant "write (to the out param)". We can't (easily) recycle a variable when decoding repeatedly because the previous value will be preserved.
Comment 6 Alex Christensen 2020-02-10 17:42:08 PST
We are moving from this model:
1. Instantiating a default-constructed value
2. Decode members into the value
3. Return the value by reference

To this model:
1. Decode all members
2. Construct an object with all members

This avoids partially initialized objects and it allows non-default-constructible objects, so we can use UniqueRef and Ref in serialized types.  It's a slow move, but we'll get there any year now.
Comment 7 Carlos Garcia Campos 2020-02-11 04:55:50 PST
Created attachment 390353 [details]
Patch for soup

It builds with this patch, but it doesn't work.
Comment 8 Ross Kirsling 2020-02-11 08:03:50 PST
(In reply to Carlos Garcia Campos from comment #7)
> Created attachment 390353 [details]
> Patch for soup
> 
> It builds with this patch, but it doesn't work.

Yeah, I should've mentioned the same for WinCairo. All relevant API tests fail, but this is probably not a platform-specific issue.
Comment 9 Fujii Hironori 2020-02-11 21:52:09 PST
Comment on attachment 390285 [details]
patch

View in context: https://bugs.webkit.org/attachment.cgi?id=390285&action=review

> Source/WebCore/platform/network/ResourceRequestBase.h:363
>  }

How about idea using Optional only for non-default-constructable class?
How about idea adding error state to decoder as well as std::ios_base::iostate?
https://en.cppreference.com/w/cpp/io/ios_base/iostate

Then, ResourceRequestBase::decodeBase can be simplified like the following.

template<class Decoder>
ALWAYS_INLINE void ResourceRequestBase::decodeBase(Decoder& decoder)
{
    String firstPartyForCookies;

    decoder >> m_url;
    decoder >> m_timeoutInterval;
    decoder >> firstPartyForCookies;
    decoder >> m_httpMethod;
    decoder >> m_httpHeaderFields;
    decoder >> m_responseContentDispositionEncodingFallbackArray;
    decoder >> m_cachePolicy;
    decoder >> m_allowCookies;
    decoder >> m_sameSiteDisposition;
    decoder >> m_isTopSite;
    decoder >> m_priority;
    decoder >> m_requester;

    if (decoder.didFail)
        return;

    m_firstPartyForCookies = URL({ }, firstPartyForCookies);
}
Comment 10 Fujii Hironori 2020-02-11 22:09:26 PST
Comment on attachment 390285 [details]
patch

View in context: https://bugs.webkit.org/attachment.cgi?id=390285&action=review

> Source/WTF/wtf/persistence/PersistentCoders.h:135
> +        tmp.reserveInitialCapacity(*size);

You added reserveInitialCapacity here.
It is dangerous to allocate memory without check bufferIsLargeEnoughToContain.
Use tryReserveCapacity and check the result.

> Source/WTF/wtf/persistence/PersistentCoders.h:201
> +        tempHashMap.reserveInitialCapacity(static_cast<unsigned>(*hashMapSize));

HashMap should have tryReserveCapacity method.
Comment 11 Alex Christensen 2020-04-10 17:25:34 PDT
I removed my reserveInitialCapacity "optimization".
We could definitely add a flag to the decoder, but we would still want to decode to Optional<T> in case it fails.  The flag would prevent us from having to check every time we call operator>>.
Comment 12 Alex Christensen 2020-04-10 17:27:42 PDT
Created attachment 396137 [details]
Patch
Comment 13 Alex Christensen 2020-04-10 17:48:14 PDT
Created attachment 396139 [details]
Patch
Comment 14 Alex Christensen 2020-04-10 18:07:12 PDT
Created attachment 396141 [details]
Patch
Comment 15 David Kilzer (:ddkilzer) 2020-04-10 19:00:53 PDT
(In reply to Alex Christensen from comment #14)
> Created attachment 396141 [details]
> Patch

Sorry, this need to be rebased after r259917.
Comment 16 David Kilzer (:ddkilzer) 2020-04-10 19:03:20 PDT
(In reply to David Kilzer (:ddkilzer) from comment #15)
> (In reply to Alex Christensen from comment #14)
> > Created attachment 396141 [details]
> > Patch
> 
> Sorry, this need to be rebased after r259917.

Actually...it might be okay.  I don't think this patch changes the same lines of code that r259917 did.
Comment 17 David Kilzer (:ddkilzer) 2020-04-10 19:19:57 PDT
Comment on attachment 396141 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=396141&action=review

> Source/WebCore/platform/network/ResourceLoadPriority.h:69
> +template<> struct EnumTraits<WebCore::ResourceLoadPriority> {
> +    using values = EnumValues<
> +        WebCore::ResourceLoadPriority,
> +        WebCore::ResourceLoadPriority::VeryLow,
> +        WebCore::ResourceLoadPriority::Low,
> +        WebCore::ResourceLoadPriority::Medium,
> +        WebCore::ResourceLoadPriority::High,
> +        WebCore::ResourceLoadPriority::VeryHigh
> +    >;
> +};

I don't think MSVC++ likes this syntax:

ResourceRequestCFNet.cpp
C:\cygwin\home\buildbot\worker\Windows-EWS\build\Source\WebCore\platform\network\ResourceLoadPriority.h(60,29): error C2988: unrecognizable template declaration/definition (compiling source file C:\cygwin\home\buildbot\worker\Windows-EWS\build\Source\WebCore\platform\network\cf\ResourceRequestCFNet.cpp) [C:\cygwin\home\buildbot\worker\Windows-EWS\build\WebKitBuild\Release\Source\WebCore\WebCore.vcxproj]
C:\cygwin\home\buildbot\worker\Windows-EWS\build\Source\WebCore\platform\network\ResourceLoadPriority.h(60,29): error C2143: syntax error: missing ';' before '<' (compiling source file C:\cygwin\home\buildbot\worker\Windows-EWS\build\Source\WebCore\platform\network\cf\ResourceRequestCFNet.cpp) [C:\cygwin\home\buildbot\worker\Windows-EWS\build\WebKitBuild\Release\Source\WebCore\WebCore.vcxproj]
C:\cygwin\home\buildbot\worker\Windows-EWS\build\Source\WebCore\platform\network\ResourceLoadPriority.h(60,12): error C2913: explicit specialization; 'WTF::EnumTraits' is not a specialization of a class template (compiling source file C:\cygwin\home\buildbot\worker\Windows-EWS\build\Source\WebCore\platform\network\cf\ResourceRequestCFNet.cpp) [C:\cygwin\home\buildbot\worker\Windows-EWS\build\WebKitBuild\Release\Source\WebCore\WebCore.vcxproj]
C:\cygwin\home\buildbot\worker\Windows-EWS\build\Source\WebCore\platform\network\ResourceLoadPriority.h(60,29): error C2059: syntax error: '<' (compiling source file C:\cygwin\home\buildbot\worker\Windows-EWS\build\Source\WebCore\platform\network\cf\ResourceRequestCFNet.cpp) [C:\cygwin\home\buildbot\worker\Windows-EWS\build\WebKitBuild\Release\Source\WebCore\WebCore.vcxproj]
C:\cygwin\home\buildbot\worker\Windows-EWS\build\Source\WebCore\platform\network\ResourceLoadPriority.h(60,61): error C2143: syntax error: missing ';' before '{' (compiling source file C:\cygwin\home\buildbot\worker\Windows-EWS\build\Source\WebCore\platform\network\cf\ResourceRequestCFNet.cpp) [C:\cygwin\home\buildbot\worker\Windows-EWS\build\WebKitBuild\Release\Source\WebCore\WebCore.vcxproj]

<https://ews-build.webkit.org/#/builders/10/builds/14701>

Does MSVC++ not like the type specifier on the enum class?

enum class ResourceLoadPriority : uint8_t {
    [...]
};
Comment 18 David Kilzer (:ddkilzer) 2020-04-10 19:21:52 PDT
Comment on attachment 396141 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=396141&action=review

>> Source/WebCore/platform/network/ResourceLoadPriority.h:69
>> +};
> 
> I don't think MSVC++ likes this syntax:
> 
> ResourceRequestCFNet.cpp
> C:\cygwin\home\buildbot\worker\Windows-EWS\build\Source\WebCore\platform\network\ResourceLoadPriority.h(60,29): error C2988: unrecognizable template declaration/definition (compiling source file C:\cygwin\home\buildbot\worker\Windows-EWS\build\Source\WebCore\platform\network\cf\ResourceRequestCFNet.cpp) [C:\cygwin\home\buildbot\worker\Windows-EWS\build\WebKitBuild\Release\Source\WebCore\WebCore.vcxproj]
> C:\cygwin\home\buildbot\worker\Windows-EWS\build\Source\WebCore\platform\network\ResourceLoadPriority.h(60,29): error C2143: syntax error: missing ';' before '<' (compiling source file C:\cygwin\home\buildbot\worker\Windows-EWS\build\Source\WebCore\platform\network\cf\ResourceRequestCFNet.cpp) [C:\cygwin\home\buildbot\worker\Windows-EWS\build\WebKitBuild\Release\Source\WebCore\WebCore.vcxproj]
> C:\cygwin\home\buildbot\worker\Windows-EWS\build\Source\WebCore\platform\network\ResourceLoadPriority.h(60,12): error C2913: explicit specialization; 'WTF::EnumTraits' is not a specialization of a class template (compiling source file C:\cygwin\home\buildbot\worker\Windows-EWS\build\Source\WebCore\platform\network\cf\ResourceRequestCFNet.cpp) [C:\cygwin\home\buildbot\worker\Windows-EWS\build\WebKitBuild\Release\Source\WebCore\WebCore.vcxproj]
> C:\cygwin\home\buildbot\worker\Windows-EWS\build\Source\WebCore\platform\network\ResourceLoadPriority.h(60,29): error C2059: syntax error: '<' (compiling source file C:\cygwin\home\buildbot\worker\Windows-EWS\build\Source\WebCore\platform\network\cf\ResourceRequestCFNet.cpp) [C:\cygwin\home\buildbot\worker\Windows-EWS\build\WebKitBuild\Release\Source\WebCore\WebCore.vcxproj]
> C:\cygwin\home\buildbot\worker\Windows-EWS\build\Source\WebCore\platform\network\ResourceLoadPriority.h(60,61): error C2143: syntax error: missing ';' before '{' (compiling source file C:\cygwin\home\buildbot\worker\Windows-EWS\build\Source\WebCore\platform\network\cf\ResourceRequestCFNet.cpp) [C:\cygwin\home\buildbot\worker\Windows-EWS\build\WebKitBuild\Release\Source\WebCore\WebCore.vcxproj]
> 
> <https://ews-build.webkit.org/#/builders/10/builds/14701>
> 
> Does MSVC++ not like the type specifier on the enum class?
> 
> enum class ResourceLoadPriority : uint8_t {
>     [...]
> };

Oh, maybe it needs this preceding it:

template<typename T> struct EnumTraits;
Comment 19 Alex Christensen 2020-04-10 21:30:10 PDT
Comment on attachment 396141 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=396141&action=review

> Source/WebCore/platform/network/ResourceRequestBase.h:419
> +        WebCore::ResourceRequestBase::Requester::ImportScripts

Yes, I need to include EnumTraits.h to fix the Windows build.  I also need to include Ping and Beacon here to fix the tests.
Comment 20 Alex Christensen 2020-04-10 21:34:03 PDT
Created attachment 396148 [details]
Patch
Comment 21 Alex Christensen 2020-04-10 22:13:23 PDT
Created attachment 396152 [details]
Patch
Comment 22 EWS 2020-04-10 23:39:41 PDT
Committed r259922: <https://trac.webkit.org/changeset/259922>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 396152 [details].
Comment 23 Radar WebKit Bug Importer 2020-04-10 23:40:16 PDT
<rdar://problem/61625504>
Comment 24 Darin Adler 2020-04-11 08:44:35 PDT
(In reply to Fujii Hironori from comment #9)
> How about idea using Optional only for non-default-constructable class?

I like this idea.