haikuwebkit/Source/WebCore/dom/PendingScriptClient.h

40 lines
1.5 KiB
C
Raw Permalink Normal View History

Make PendingScript as ref-counted https://bugs.webkit.org/show_bug.cgi?id=161350 Reviewed by Ryosuke Niwa. Currently, while PendingScript is copyable, PendingScript is also CachedResourceClient. So when copying this, the client registration is done in PendingScript's operator= etc. However, this copying functionality is not effectively used. In this patch, we change this PendingScript to ref-counted class and make it noncopyable. This change makes things simple (dropping this copying functionality), and drops unnecessary addClient / removeClient calls. And we also simplify PendingScript class. Since we can offer all the members at the construction time, we do not need any setters like setCachedScript, setElement etc. This prevents us from accidentally generating the half-baked pending script. Furthermore, by changing PendingScript noncopyable & ref-counted, we easily make it observable. In this patch, we add PendingScriptClient to receive the notification from PendingScript. Previously, we directly used CachedScript in PendingScript to receive the notification. When introducing ScriptModuleGraph and making this PendingScript the container of the both CachedScript and ScriptModuleGraph, hiding the raw CachedScript operations is useful. No behavior changes. * WebCore.xcodeproj/project.pbxproj: * dom/PendingScript.cpp: (WebCore::PendingScript::create): These factory functions take all the information needed to construct the PendingScript. So the setters of PendingScript are dropped. This is better since we now do not expose any half-baked pending script accidentally. (WebCore::PendingScript::PendingScript): (WebCore::PendingScript::~PendingScript): (WebCore::PendingScript::notifyClientFinished): (WebCore::PendingScript::notifyFinished): (WebCore::PendingScript::isLoaded): When introducing ScriptModuleGraph, this will query to either CachedScript or ScriptModuleGraph. PendingScript will become the container for the both types. (WebCore::PendingScript::setClient): (WebCore::PendingScript::clearClient): PendingScript is now observable by PendingScriptClient. This avoids touching CachedScript in PendingScript directly. That is good when we introduce ScriptModuleGraph and make PendingScript the container of the both CachedScript and ScriptModuleGraph. (WebCore::PendingScript::releaseElementAndClear): Deleted. Previously, PendingScript is not ref-counted. So when we would like to say "this pending script is empty", we used the pending script with `m_element = nullptr`. This releaseElementAndClear cleared this m_element and made the pending script empty. Now, we use RefPtr<PendingScript> and empty one is just represented by the nullptr. This function is no longer necessary. Dropped. (WebCore::PendingScript::setCachedScript): Deleted. The fields are set in the constructor. So this setter is no longer necessary. Dropped. * dom/PendingScript.h: * dom/PendingScriptClient.h: Copied from Source/WebCore/html/parser/HTMLScriptRunnerHost.h. (WebCore::PendingScriptClient::~PendingScriptClient): * dom/ScriptRunner.cpp: (WebCore::ScriptRunner::queueScriptForExecution): (WebCore::ScriptRunner::notifyScriptReady): (WebCore::ScriptRunner::timerFired): We use `std::exchange` to retrieve the RefPtr<PendingScript> and make the original vector element nullptr. Without this, all the PendingScript is held until the iteration finishes. We keep the original semantics here that the pending script can be released per iteration. * dom/ScriptRunner.h: * html/parser/HTMLDocumentParser.cpp: (WebCore::HTMLDocumentParser::watchForLoad): (WebCore::HTMLDocumentParser::stopWatchingForLoad): Use PendingScript instead of touching CachedScript directly. (WebCore::HTMLDocumentParser::notifyFinished): * html/parser/HTMLDocumentParser.h: * html/parser/HTMLScriptRunner.cpp: (WebCore::HTMLScriptRunner::~HTMLScriptRunner): (WebCore::HTMLScriptRunner::sourceFromPendingScript): (WebCore::HTMLScriptRunner::isPendingScriptReady): (WebCore::HTMLScriptRunner::executeParsingBlockingScript): (WebCore::HTMLScriptRunner::executePendingScriptAndDispatchEvent): As the previous comment describes, we used releaseElementAndClear to make the current pending script empty. Instead of doing so, we now explicitly clear executeParsingBlockingScript (by assigning nullptr to m_parserBlockingScript). (WebCore::HTMLScriptRunner::watchForLoad): (WebCore::HTMLScriptRunner::stopWatchingForLoad): Previously, we used CachedScript::addClient directly in the m_host.watchForLoad. This means that we did not have a quick way to query whether the pending script is watched. In the old implementation, we have the `m_watchingForLoad : bool` flag in PendingScript to hold the watching status for the given pending script. This `pendingScript.setWatchingForLoad(true)` just made this flag `true`. But now, we do not use CachedScript::addClient directly. Instead, we have the PendingScriptClient and PendingScript::{setClient,clearClient}. We can know whether this pending script is watched by checking `m_client != nullptr`. This makes `m_watchingForLoad` unnecessary. So this patch drops `m_watchingForLoad` and `pendingScript.setWatchingForLoad(true)` call. (WebCore::HTMLScriptRunner::hasParserBlockingScript): (WebCore::HTMLScriptRunner::executeParsingBlockingScripts): We clear the m_parserBlockingScript here instead of the middle of the executePendingScriptAndDispatchEvent. (WebCore::HTMLScriptRunner::executeScriptsWaitingForLoad): (WebCore::HTMLScriptRunner::executeScriptsWaitingForParsing): (WebCore::requestPendingScript): (WebCore::HTMLScriptRunner::requestParsingBlockingScript): Setting m_parsingBlockingScript is now done in this caller side. (WebCore::HTMLScriptRunner::requestDeferredScript): (WebCore::HTMLScriptRunner::runScript): (WebCore::HTMLScriptRunner::requestPendingScript): Instead of configuring the passed PendingScript&, we return the pending script and the caller sets it to m_parserBlockingScript or holds it. And we now change this function to static location one and drop the member function. Previously, we always make PendingScript& valid by always calling `setElement(...)`. I think this is the bug since we accidentally exposed the half-baked pending script. But this bug is not shown since `!cachedScript` path is dead code! This requestPendingScript is called from two places, requestDeferredScript and requestParsingBlockingScript. And these functions are called if the script has `willBeParserExecuted` flag. In the case of the script tag having "src" attribute, this flag is only set if `cachedScript` is correctly instantiated. So when these functions are called, we can ensure that `cachedScript` is correctly instantiated for the given script. In the case of the script tag not having "src" attribute, these functions are won't be called. This is because if such a script tag has `willBeParserExecuted` flag, it also has `m_readyToBeParserExecuted` and it does not have `m_willExecuteWhenDocumentFinishedParsing` flag, and in that case the both functions are never called. So we drop that path and insert the assertion to ensure the above conditions. * html/parser/HTMLScriptRunner.h: * html/parser/HTMLScriptRunnerHost.h: Canonical link: https://commits.webkit.org/179581@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@205218 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-08-31 02:37:12 +00:00
/*
* Copyright (C) 2016 Apple, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
namespace WebCore {
class PendingScript;
class PendingScriptClient {
public:
Use "= default" to denote default constructor or destructor https://bugs.webkit.org/show_bug.cgi?id=178528 Rubber-stamped by Andy Estes. Source/WebCore: * Modules/airplay/WebKitPlaybackTargetAvailabilityEvent.h: * Modules/applepay/ApplePayError.cpp: * Modules/applepay/ApplePayPaymentAuthorizedEvent.cpp: * Modules/applepay/ApplePayPaymentMethodSelectedEvent.cpp: * Modules/applepay/ApplePaySession.cpp: * Modules/applepay/ApplePaySessionPaymentRequest.cpp: * Modules/applepay/ApplePayShippingContactSelectedEvent.cpp: * Modules/applepay/ApplePayShippingMethodSelectedEvent.cpp: * Modules/applepay/ApplePayValidateMerchantEvent.cpp: * Modules/applepay/Payment.h: * Modules/applepay/PaymentCoordinatorClient.h: * Modules/credentials/BasicCredential.cpp: * Modules/credentials/FederatedCredential.cpp: * Modules/credentials/NavigatorCredentials.cpp: * Modules/credentials/PasswordCredential.cpp: * Modules/encryptedmedia/CDMClient.h: * Modules/encryptedmedia/legacy/LegacyCDM.cpp: * Modules/encryptedmedia/legacy/LegacyCDM.h: * Modules/encryptedmedia/legacy/LegacyCDMPrivate.h: * Modules/encryptedmedia/legacy/LegacyCDMPrivateClearKey.h: * Modules/encryptedmedia/legacy/LegacyCDMPrivateMediaPlayer.h: * Modules/encryptedmedia/legacy/LegacyCDMSessionClearKey.cpp: * Modules/encryptedmedia/legacy/WebKitMediaKeyMessageEvent.cpp: * Modules/encryptedmedia/legacy/WebKitMediaKeyNeededEvent.cpp: * Modules/entriesapi/DOMFileSystem.cpp: * Modules/entriesapi/FileSystemDirectoryReader.cpp: * Modules/entriesapi/FileSystemEntry.cpp: * Modules/fetch/FetchLoaderClient.h: * Modules/gamepad/Gamepad.cpp: * Modules/gamepad/GamepadEvent.h: * Modules/gamepad/deprecated/Gamepad.cpp: [ truncated ] Source/WebCore/PAL: * pal/Logger.h: (PAL::Logger::Observer::~Observer): Deleted. * pal/crypto/gcrypt/CryptoDigestGCrypt.cpp: * pal/system/SleepDisabler.cpp: * pal/system/SystemSleepListener.h: Canonical link: https://commits.webkit.org/194740@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223728 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-19 23:48:45 +00:00
virtual ~PendingScriptClient() = default;
Make PendingScript as ref-counted https://bugs.webkit.org/show_bug.cgi?id=161350 Reviewed by Ryosuke Niwa. Currently, while PendingScript is copyable, PendingScript is also CachedResourceClient. So when copying this, the client registration is done in PendingScript's operator= etc. However, this copying functionality is not effectively used. In this patch, we change this PendingScript to ref-counted class and make it noncopyable. This change makes things simple (dropping this copying functionality), and drops unnecessary addClient / removeClient calls. And we also simplify PendingScript class. Since we can offer all the members at the construction time, we do not need any setters like setCachedScript, setElement etc. This prevents us from accidentally generating the half-baked pending script. Furthermore, by changing PendingScript noncopyable & ref-counted, we easily make it observable. In this patch, we add PendingScriptClient to receive the notification from PendingScript. Previously, we directly used CachedScript in PendingScript to receive the notification. When introducing ScriptModuleGraph and making this PendingScript the container of the both CachedScript and ScriptModuleGraph, hiding the raw CachedScript operations is useful. No behavior changes. * WebCore.xcodeproj/project.pbxproj: * dom/PendingScript.cpp: (WebCore::PendingScript::create): These factory functions take all the information needed to construct the PendingScript. So the setters of PendingScript are dropped. This is better since we now do not expose any half-baked pending script accidentally. (WebCore::PendingScript::PendingScript): (WebCore::PendingScript::~PendingScript): (WebCore::PendingScript::notifyClientFinished): (WebCore::PendingScript::notifyFinished): (WebCore::PendingScript::isLoaded): When introducing ScriptModuleGraph, this will query to either CachedScript or ScriptModuleGraph. PendingScript will become the container for the both types. (WebCore::PendingScript::setClient): (WebCore::PendingScript::clearClient): PendingScript is now observable by PendingScriptClient. This avoids touching CachedScript in PendingScript directly. That is good when we introduce ScriptModuleGraph and make PendingScript the container of the both CachedScript and ScriptModuleGraph. (WebCore::PendingScript::releaseElementAndClear): Deleted. Previously, PendingScript is not ref-counted. So when we would like to say "this pending script is empty", we used the pending script with `m_element = nullptr`. This releaseElementAndClear cleared this m_element and made the pending script empty. Now, we use RefPtr<PendingScript> and empty one is just represented by the nullptr. This function is no longer necessary. Dropped. (WebCore::PendingScript::setCachedScript): Deleted. The fields are set in the constructor. So this setter is no longer necessary. Dropped. * dom/PendingScript.h: * dom/PendingScriptClient.h: Copied from Source/WebCore/html/parser/HTMLScriptRunnerHost.h. (WebCore::PendingScriptClient::~PendingScriptClient): * dom/ScriptRunner.cpp: (WebCore::ScriptRunner::queueScriptForExecution): (WebCore::ScriptRunner::notifyScriptReady): (WebCore::ScriptRunner::timerFired): We use `std::exchange` to retrieve the RefPtr<PendingScript> and make the original vector element nullptr. Without this, all the PendingScript is held until the iteration finishes. We keep the original semantics here that the pending script can be released per iteration. * dom/ScriptRunner.h: * html/parser/HTMLDocumentParser.cpp: (WebCore::HTMLDocumentParser::watchForLoad): (WebCore::HTMLDocumentParser::stopWatchingForLoad): Use PendingScript instead of touching CachedScript directly. (WebCore::HTMLDocumentParser::notifyFinished): * html/parser/HTMLDocumentParser.h: * html/parser/HTMLScriptRunner.cpp: (WebCore::HTMLScriptRunner::~HTMLScriptRunner): (WebCore::HTMLScriptRunner::sourceFromPendingScript): (WebCore::HTMLScriptRunner::isPendingScriptReady): (WebCore::HTMLScriptRunner::executeParsingBlockingScript): (WebCore::HTMLScriptRunner::executePendingScriptAndDispatchEvent): As the previous comment describes, we used releaseElementAndClear to make the current pending script empty. Instead of doing so, we now explicitly clear executeParsingBlockingScript (by assigning nullptr to m_parserBlockingScript). (WebCore::HTMLScriptRunner::watchForLoad): (WebCore::HTMLScriptRunner::stopWatchingForLoad): Previously, we used CachedScript::addClient directly in the m_host.watchForLoad. This means that we did not have a quick way to query whether the pending script is watched. In the old implementation, we have the `m_watchingForLoad : bool` flag in PendingScript to hold the watching status for the given pending script. This `pendingScript.setWatchingForLoad(true)` just made this flag `true`. But now, we do not use CachedScript::addClient directly. Instead, we have the PendingScriptClient and PendingScript::{setClient,clearClient}. We can know whether this pending script is watched by checking `m_client != nullptr`. This makes `m_watchingForLoad` unnecessary. So this patch drops `m_watchingForLoad` and `pendingScript.setWatchingForLoad(true)` call. (WebCore::HTMLScriptRunner::hasParserBlockingScript): (WebCore::HTMLScriptRunner::executeParsingBlockingScripts): We clear the m_parserBlockingScript here instead of the middle of the executePendingScriptAndDispatchEvent. (WebCore::HTMLScriptRunner::executeScriptsWaitingForLoad): (WebCore::HTMLScriptRunner::executeScriptsWaitingForParsing): (WebCore::requestPendingScript): (WebCore::HTMLScriptRunner::requestParsingBlockingScript): Setting m_parsingBlockingScript is now done in this caller side. (WebCore::HTMLScriptRunner::requestDeferredScript): (WebCore::HTMLScriptRunner::runScript): (WebCore::HTMLScriptRunner::requestPendingScript): Instead of configuring the passed PendingScript&, we return the pending script and the caller sets it to m_parserBlockingScript or holds it. And we now change this function to static location one and drop the member function. Previously, we always make PendingScript& valid by always calling `setElement(...)`. I think this is the bug since we accidentally exposed the half-baked pending script. But this bug is not shown since `!cachedScript` path is dead code! This requestPendingScript is called from two places, requestDeferredScript and requestParsingBlockingScript. And these functions are called if the script has `willBeParserExecuted` flag. In the case of the script tag having "src" attribute, this flag is only set if `cachedScript` is correctly instantiated. So when these functions are called, we can ensure that `cachedScript` is correctly instantiated for the given script. In the case of the script tag not having "src" attribute, these functions are won't be called. This is because if such a script tag has `willBeParserExecuted` flag, it also has `m_readyToBeParserExecuted` and it does not have `m_willExecuteWhenDocumentFinishedParsing` flag, and in that case the both functions are never called. So we drop that path and insert the assertion to ensure the above conditions. * html/parser/HTMLScriptRunner.h: * html/parser/HTMLScriptRunnerHost.h: Canonical link: https://commits.webkit.org/179581@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@205218 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-08-31 02:37:12 +00:00
virtual void notifyFinished(PendingScript&) = 0;
};
}