/*
 * Copyright (C) 2008-2017 Apple Inc. All Rights Reserved.
 * Copyright (C) 2009, 2011 Google 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.
 *
 */

#include "config.h"
#include "WorkerGlobalScope.h"

#include "BlobURL.h"
#include "CSSFontSelector.h"
#include "CSSValueList.h"
#include "CSSValuePool.h"
#include "CommonVM.h"
#include "ContentSecurityPolicy.h"
#include "Crypto.h"
#include "FontCustomPlatformData.h"
#include "FontFaceSet.h"
#include "IDBConnectionProxy.h"
#include "ImageBitmapOptions.h"
#include "InspectorInstrumentation.h"
#include "JSDOMExceptionHandling.h"
#include "Performance.h"
#include "RTCDataChannelRemoteHandlerConnection.h"
#include "RuntimeEnabledFeatures.h"
#include "ScheduledAction.h"
#include "ScriptSourceCode.h"
#include "SecurityOrigin.h"
#include "SecurityOriginPolicy.h"
#include "ServiceWorker.h"
#include "ServiceWorkerClientData.h"
#include "ServiceWorkerGlobalScope.h"
#include "SocketProvider.h"
#include "WorkerCacheStorageConnection.h"
#include "WorkerFileSystemStorageConnection.h"
#include "WorkerFontLoadRequest.h"
#include "WorkerLoaderProxy.h"
#include "WorkerLocation.h"
#include "WorkerMessagePortChannelProvider.h"
#include "WorkerMessagingProxy.h"
#include "WorkerNavigator.h"
#include "WorkerOrWorkletGlobalScope.h"
#include "WorkerReportingProxy.h"
#include "WorkerSWClientConnection.h"
#include "WorkerScriptLoader.h"
#include "WorkerStorageConnection.h"
#include "WorkerThread.h"
#include <JavaScriptCore/ScriptArguments.h>
#include <JavaScriptCore/ScriptCallStack.h>
#include <wtf/IsoMallocInlines.h>
#include <wtf/Lock.h>
#include <wtf/WorkQueue.h>
#include <wtf/threads/BinarySemaphore.h>

namespace WebCore {
using namespace Inspector;

static Lock allWorkerGlobalScopeIdentifiersLock;
static HashSet<ScriptExecutionContextIdentifier>& allWorkerGlobalScopeIdentifiers() WTF_REQUIRES_LOCK(allWorkerGlobalScopeIdentifiersLock)
{
    static NeverDestroyed<HashSet<ScriptExecutionContextIdentifier>> identifiers;
    ASSERT(allWorkerGlobalScopeIdentifiersLock.isLocked());
    return identifiers;
}

static WorkQueue& sharedFileSystemStorageQueue()
{
    static NeverDestroyed<Ref<WorkQueue>> queue(WorkQueue::create("Shared File System Storage Queue",  WorkQueue::QOS::Default));
    return queue.get();
}

WTF_MAKE_ISO_ALLOCATED_IMPL(WorkerGlobalScope);

WorkerGlobalScope::WorkerGlobalScope(WorkerThreadType type, const WorkerParameters& params, Ref<SecurityOrigin>&& origin, WorkerThread& thread, Ref<SecurityOrigin>&& topOrigin, IDBClient::IDBConnectionProxy* connectionProxy, SocketProvider* socketProvider)
    : WorkerOrWorkletGlobalScope(type, params.sessionID, isMainThread() ? Ref { commonVM() } : JSC::VM::create(), &thread, params.clientIdentifier)
    , m_url(params.scriptURL)
    , m_inspectorIdentifier(params.inspectorIdentifier)
    , m_userAgent(params.userAgent)
    , m_isOnline(params.isOnline)
    , m_shouldBypassMainWorldContentSecurityPolicy(params.shouldBypassMainWorldContentSecurityPolicy)
    , m_topOrigin(WTFMove(topOrigin))
    , m_connectionProxy(connectionProxy)
    , m_socketProvider(socketProvider)
    , m_performance(Performance::create(this, params.timeOrigin))
    , m_referrerPolicy(params.referrerPolicy)
    , m_settingsValues(params.settingsValues)
    , m_workerType(params.workerType)
    , m_credentials(params.credentials)
{
    {
        Locker locker { allWorkerGlobalScopeIdentifiersLock };
        allWorkerGlobalScopeIdentifiers().add(identifier());
    }

    if (m_topOrigin->hasUniversalAccess())
        origin->grantUniversalAccess();
    if (m_topOrigin->needsStorageAccessFromFileURLsQuirk())
        origin->grantStorageAccessFromFileURLsQuirk();

    setStorageBlockingPolicy(m_settingsValues.storageBlockingPolicy);
    setSecurityOriginPolicy(SecurityOriginPolicy::create(WTFMove(origin)));
    setContentSecurityPolicy(makeUnique<ContentSecurityPolicy>(URL { m_url }, *this));
    setCrossOriginEmbedderPolicy(params.crossOriginEmbedderPolicy);
}

WorkerGlobalScope::~WorkerGlobalScope()
{
    ASSERT(thread().thread() == &Thread::current());
    // We need to remove from the contexts map very early in the destructor so that calling postTask() on this WorkerGlobalScope from another thread is safe.
    removeFromContextsMap();

    {
        Locker locker { allWorkerGlobalScopeIdentifiersLock };
        allWorkerGlobalScopeIdentifiers().remove(identifier());
    }

    m_performance = nullptr;
    m_crypto = nullptr;

    // Notify proxy that we are going away. This can free the WorkerThread object, so do not access it after this.
    thread().workerReportingProxy().workerGlobalScopeDestroyed();
}

String WorkerGlobalScope::origin() const
{
    auto* securityOrigin = this->securityOrigin();
    return securityOrigin ? securityOrigin->toString() : emptyString();
}

void WorkerGlobalScope::prepareForDestruction()
{
    WorkerOrWorkletGlobalScope::prepareForDestruction();

#if ENABLE(SERVICE_WORKER)
    if (settingsValues().serviceWorkersEnabled)
        swClientConnection().unregisterServiceWorkerClient(identifier());
#endif

    stopIndexedDatabase();

    if (m_cacheStorageConnection)
        m_cacheStorageConnection->clearPendingRequests();

    if (m_storageConnection)
        m_storageConnection->scopeClosed();

    if (m_fileSystemStorageConnection)
        m_fileSystemStorageConnection->scopeClosed();
}

void WorkerGlobalScope::removeAllEventListeners()
{
    WorkerOrWorkletGlobalScope::removeAllEventListeners();
    m_performance->removeAllEventListeners();
    m_performance->removeAllObservers();
}

bool WorkerGlobalScope::isSecureContext() const
{
    if (!RuntimeEnabledFeatures::sharedFeatures().secureContextChecksEnabled())
        return true;

    return securityOrigin() && securityOrigin()->isPotentiallyTrustworthy();
}

void WorkerGlobalScope::applyContentSecurityPolicyResponseHeaders(const ContentSecurityPolicyResponseHeaders& contentSecurityPolicyResponseHeaders)
{
    contentSecurityPolicy()->didReceiveHeaders(contentSecurityPolicyResponseHeaders, String { });
}

URL WorkerGlobalScope::completeURL(const String& url, ForceUTF8) const
{
    // Always return a null URL when passed a null string.
    // FIXME: Should we change the URL constructor to have this behavior?
    if (url.isNull())
        return URL();
    // Always use UTF-8 in Workers.
    return URL(m_url, url);
}

String WorkerGlobalScope::userAgent(const URL&) const
{
    return m_userAgent;
}

SocketProvider* WorkerGlobalScope::socketProvider()
{
    return m_socketProvider.get();
}

RefPtr<RTCDataChannelRemoteHandlerConnection> WorkerGlobalScope::createRTCDataChannelRemoteHandlerConnection()
{
    RefPtr<RTCDataChannelRemoteHandlerConnection> connection;
    callOnMainThreadAndWait([workerThread = Ref { thread() }, &connection]() mutable {
        connection = workerThread->workerLoaderProxy().createRTCDataChannelRemoteHandlerConnection();
    });
    ASSERT(connection);

    return connection;
}

IDBClient::IDBConnectionProxy* WorkerGlobalScope::idbConnectionProxy()
{
    return m_connectionProxy.get();
}

void WorkerGlobalScope::stopIndexedDatabase()
{
    if (m_connectionProxy)
        m_connectionProxy->forgetActivityForCurrentThread();
}

void WorkerGlobalScope::suspend()
{
    if (m_connectionProxy)
        m_connectionProxy->setContextSuspended(*this, true);

#if ENABLE(SERVICE_WORKER)
    if (settingsValues().serviceWorkersEnabled)
        swClientConnection().unregisterServiceWorkerClient(identifier());
#endif
}

void WorkerGlobalScope::resume()
{
#if ENABLE(SERVICE_WORKER)
    if (settingsValues().serviceWorkersEnabled)
        updateServiceWorkerClientData();
#endif

    if (m_connectionProxy)
        m_connectionProxy->setContextSuspended(*this, false);
}

WorkerStorageConnection& WorkerGlobalScope::storageConnection()
{
    if (!m_storageConnection)
        m_storageConnection = WorkerStorageConnection::create(*this);

    return *m_storageConnection;
}

void WorkerGlobalScope::postFileSystemStorageTask(Function<void()>&& task)
{
    sharedFileSystemStorageQueue().dispatch(WTFMove(task));
}

WorkerFileSystemStorageConnection& WorkerGlobalScope::getFileSystemStorageConnection(Ref<FileSystemStorageConnection>&& mainThreadConnection)
{
    if (!m_fileSystemStorageConnection)
        m_fileSystemStorageConnection = WorkerFileSystemStorageConnection::create(*this, WTFMove(mainThreadConnection));
    else if (m_fileSystemStorageConnection->mainThreadConnection() != mainThreadConnection.ptr()) {
        m_fileSystemStorageConnection->connectionClosed();
        m_fileSystemStorageConnection = WorkerFileSystemStorageConnection::create(*this, WTFMove(mainThreadConnection));
    }

    return *m_fileSystemStorageConnection;
}

WorkerFileSystemStorageConnection* WorkerGlobalScope::fileSystemStorageConnection()
{
    return m_fileSystemStorageConnection.get();
}

WorkerLocation& WorkerGlobalScope::location() const
{
    if (!m_location)
        m_location = WorkerLocation::create(URL { m_url }, origin());
    return *m_location;
}

void WorkerGlobalScope::close()
{
    if (isClosing())
        return;

    // Let current script run to completion but prevent future script evaluations.
    // After m_closing is set, all the tasks in the queue continue to be fetched but only
    // tasks with isCleanupTask()==true will be executed.
    markAsClosing();
    postTask({ ScriptExecutionContext::Task::CleanupTask, [] (ScriptExecutionContext& context) {
        ASSERT_WITH_SECURITY_IMPLICATION(is<WorkerGlobalScope>(context));
        WorkerGlobalScope& workerGlobalScope = downcast<WorkerGlobalScope>(context);
        // Notify parent that this context is closed. Parent is responsible for calling WorkerThread::stop().
        workerGlobalScope.thread().workerReportingProxy().workerGlobalScopeClosed();
    } });
}

WorkerNavigator& WorkerGlobalScope::navigator()
{
    if (!m_navigator)
        m_navigator = WorkerNavigator::create(*this, m_userAgent, m_isOnline);
    return *m_navigator;
}

void WorkerGlobalScope::setIsOnline(bool isOnline)
{
    m_isOnline = isOnline;
    if (m_navigator)
        m_navigator->setIsOnline(isOnline);
}

ExceptionOr<int> WorkerGlobalScope::setTimeout(std::unique_ptr<ScheduledAction> action, int timeout, FixedVector<JSC::Strong<JSC::Unknown>>&& arguments)
{
    // FIXME: Should this check really happen here? Or should it happen when code is about to eval?
    if (action->type() == ScheduledAction::Type::Code) {
        if (!contentSecurityPolicy()->allowEval(globalObject(), LogToConsole::Yes, action->code()))
            return 0;
    }

    action->addArguments(WTFMove(arguments));

    return DOMTimer::install(*this, WTFMove(action), Seconds::fromMilliseconds(timeout), true);
}

void WorkerGlobalScope::clearTimeout(int timeoutId)
{
    DOMTimer::removeById(*this, timeoutId);
}

ExceptionOr<int> WorkerGlobalScope::setInterval(std::unique_ptr<ScheduledAction> action, int timeout, FixedVector<JSC::Strong<JSC::Unknown>>&& arguments)
{
    // FIXME: Should this check really happen here? Or should it happen when code is about to eval?
    if (action->type() == ScheduledAction::Type::Code) {
        if (!contentSecurityPolicy()->allowEval(globalObject(), LogToConsole::Yes, action->code()))
            return 0;
    }

    action->addArguments(WTFMove(arguments));

    return DOMTimer::install(*this, WTFMove(action), Seconds::fromMilliseconds(timeout), false);
}

void WorkerGlobalScope::clearInterval(int timeoutId)
{
    DOMTimer::removeById(*this, timeoutId);
}

ExceptionOr<void> WorkerGlobalScope::importScripts(const FixedVector<String>& urls)
{
    ASSERT(contentSecurityPolicy());

    // https://html.spec.whatwg.org/multipage/workers.html#importing-scripts-and-libraries
    // 1. If worker global scope's type is "module", throw a TypeError exception.
    if (m_workerType == WorkerType::Module)
        return Exception { TypeError, "importScripts cannot be used if worker type is \"module\""_s };

    Vector<URL> completedURLs;
    Vector<BlobURLHandle> protectedBlobURLs;
    completedURLs.reserveInitialCapacity(urls.size());
    for (auto& entry : urls) {
        URL url = completeURL(entry);
        if (!url.isValid())
            return Exception { SyntaxError };
        if (url.protocolIsBlob())
            protectedBlobURLs.append(BlobURLHandle { url });
        completedURLs.uncheckedAppend(WTFMove(url));
    }

    FetchOptions::Cache cachePolicy = FetchOptions::Cache::Default;

#if ENABLE(SERVICE_WORKER)
    bool isServiceWorkerGlobalScope = is<ServiceWorkerGlobalScope>(*this);
    if (isServiceWorkerGlobalScope) {
        // FIXME: We need to add support for the 'imported scripts updated' flag as per:
        // https://w3c.github.io/ServiceWorker/#importscripts
        auto& serviceWorkerGlobalScope = downcast<ServiceWorkerGlobalScope>(*this);
        auto& registration = serviceWorkerGlobalScope.registration();
        if (registration.updateViaCache() == ServiceWorkerUpdateViaCache::None || registration.needsUpdate())
            cachePolicy = FetchOptions::Cache::NoCache;
    }
#endif

    for (auto& url : completedURLs) {
        // FIXME: Convert this to check the isolated world's Content Security Policy once webkit.org/b/104520 is solved.
        bool shouldBypassMainWorldContentSecurityPolicy = this->shouldBypassMainWorldContentSecurityPolicy();
        if (!shouldBypassMainWorldContentSecurityPolicy && !contentSecurityPolicy()->allowScriptFromSource(url))
            return Exception { NetworkError };

        auto scriptLoader = WorkerScriptLoader::create();
        auto cspEnforcement = shouldBypassMainWorldContentSecurityPolicy ? ContentSecurityPolicyEnforcement::DoNotEnforce : ContentSecurityPolicyEnforcement::EnforceScriptSrcDirective;
        if (auto exception = scriptLoader->loadSynchronously(this, url, WorkerScriptLoader::Source::ClassicWorkerImport, FetchOptions::Mode::NoCors, cachePolicy, cspEnforcement, resourceRequestIdentifier()))
            return WTFMove(*exception);

        InspectorInstrumentation::scriptImported(*this, scriptLoader->identifier(), scriptLoader->script().toString());

        WeakPtr<ScriptBufferSourceProvider> sourceProvider;
        {
            NakedPtr<JSC::Exception> exception;
            ScriptSourceCode sourceCode(scriptLoader->script(), URL(scriptLoader->responseURL()));
            sourceProvider = static_cast<ScriptBufferSourceProvider&>(sourceCode.provider());
            script()->evaluate(sourceCode, exception);
            if (exception) {
                script()->setException(exception);
                return { };
            }
        }
        if (sourceProvider)
            addImportedScriptSourceProvider(url, *sourceProvider);
    }

    return { };
}

EventTarget* WorkerGlobalScope::errorEventTarget()
{
    return this;
}

void WorkerGlobalScope::logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, RefPtr<ScriptCallStack>&&)
{
    thread().workerReportingProxy().postExceptionToWorkerObject(errorMessage, lineNumber, columnNumber, sourceURL);
}

void WorkerGlobalScope::addConsoleMessage(std::unique_ptr<Inspector::ConsoleMessage>&& message)
{
    if (!isContextThread()) {
        postTask(AddConsoleMessageTask(message->source(), message->level(), message->message()));
        return;
    }

    InspectorInstrumentation::addMessageToConsole(*this, WTFMove(message));
}

void WorkerGlobalScope::addConsoleMessage(MessageSource source, MessageLevel level, const String& message, unsigned long requestIdentifier)
{
    addMessage(source, level, message, { }, 0, 0, nullptr, nullptr, requestIdentifier);
}

void WorkerGlobalScope::addMessage(MessageSource source, MessageLevel level, const String& messageText, const String& sourceURL, unsigned lineNumber, unsigned columnNumber, RefPtr<ScriptCallStack>&& callStack, JSC::JSGlobalObject* state, unsigned long requestIdentifier)
{
    if (!isContextThread()) {
        postTask(AddConsoleMessageTask(source, level, messageText));
        return;
    }

    std::unique_ptr<Inspector::ConsoleMessage> message;
    if (callStack)
        message = makeUnique<Inspector::ConsoleMessage>(source, MessageType::Log, level, messageText, callStack.releaseNonNull(), requestIdentifier);
    else
        message = makeUnique<Inspector::ConsoleMessage>(source, MessageType::Log, level, messageText, sourceURL, lineNumber, columnNumber, state, requestIdentifier);
    InspectorInstrumentation::addMessageToConsole(*this, WTFMove(message));
}

#if ENABLE(WEB_CRYPTO)

bool WorkerGlobalScope::wrapCryptoKey(const Vector<uint8_t>& key, Vector<uint8_t>& wrappedKey)
{
    Ref protectedThis { *this };
    bool success = false;
    BinarySemaphore semaphore;
    thread().workerLoaderProxy().postTaskToLoader([&semaphore, &success, &key, &wrappedKey](auto& context) {
        success = context.wrapCryptoKey(key, wrappedKey);
        semaphore.signal();
    });
    semaphore.wait();
    return success;
}

bool WorkerGlobalScope::unwrapCryptoKey(const Vector<uint8_t>& wrappedKey, Vector<uint8_t>& key)
{
    Ref protectedThis { *this };
    bool success = false;
    BinarySemaphore semaphore;
    thread().workerLoaderProxy().postTaskToLoader([&semaphore, &success, &key, &wrappedKey](auto& context) {
        success = context.unwrapCryptoKey(wrappedKey, key);
        semaphore.signal();
    });
    semaphore.wait();
    return success;
}

#endif // ENABLE(WEB_CRYPTO)

Crypto& WorkerGlobalScope::crypto()
{
    if (!m_crypto)
        m_crypto = Crypto::create(this);
    return *m_crypto;
}

Performance& WorkerGlobalScope::performance() const
{
    return *m_performance;
}

WorkerCacheStorageConnection& WorkerGlobalScope::cacheStorageConnection()
{
    if (!m_cacheStorageConnection)
        m_cacheStorageConnection = WorkerCacheStorageConnection::create(*this);
    return *m_cacheStorageConnection;
}

MessagePortChannelProvider& WorkerGlobalScope::messagePortChannelProvider()
{
    if (!m_messagePortChannelProvider)
        m_messagePortChannelProvider = makeUnique<WorkerMessagePortChannelProvider>(*this);
    return *m_messagePortChannelProvider;
}

#if ENABLE(SERVICE_WORKER)
WorkerSWClientConnection& WorkerGlobalScope::swClientConnection()
{
    if (!m_swClientConnection)
        m_swClientConnection = WorkerSWClientConnection::create(*this);
    return *m_swClientConnection;
}
#endif

void WorkerGlobalScope::createImageBitmap(ImageBitmap::Source&& source, ImageBitmapOptions&& options, ImageBitmap::Promise&& promise)
{
    ImageBitmap::createPromise(*this, WTFMove(source), WTFMove(options), WTFMove(promise));
}

void WorkerGlobalScope::createImageBitmap(ImageBitmap::Source&& source, int sx, int sy, int sw, int sh, ImageBitmapOptions&& options, ImageBitmap::Promise&& promise)
{
    ImageBitmap::createPromise(*this, WTFMove(source), WTFMove(options), sx, sy, sw, sh, WTFMove(promise));
}

CSSValuePool& WorkerGlobalScope::cssValuePool()
{
    if (!m_cssValuePool)
        m_cssValuePool = makeUnique<CSSValuePool>();
    return *m_cssValuePool;
}

CSSFontSelector* WorkerGlobalScope::cssFontSelector()
{
    if (!m_cssFontSelector)
        m_cssFontSelector = CSSFontSelector::create(*this);
    return m_cssFontSelector.get();
}

Ref<FontFaceSet> WorkerGlobalScope::fonts()
{
    ASSERT(cssFontSelector());
    return cssFontSelector()->fontFaceSet();
}

std::unique_ptr<FontLoadRequest> WorkerGlobalScope::fontLoadRequest(String& url, bool, bool, LoadedFromOpaqueSource loadedFromOpaqueSource)
{
    return makeUnique<WorkerFontLoadRequest>(completeURL(url), loadedFromOpaqueSource);
}

void WorkerGlobalScope::beginLoadingFontSoon(FontLoadRequest& request)
{
    ASSERT(is<WorkerFontLoadRequest>(request));
    downcast<WorkerFontLoadRequest>(request).load(*this);
}

ReferrerPolicy WorkerGlobalScope::referrerPolicy() const
{
    return m_referrerPolicy;
}

WorkerThread& WorkerGlobalScope::thread() const
{
    return *static_cast<WorkerThread*>(workerOrWorkletThread());
}

void WorkerGlobalScope::releaseMemory(Synchronous synchronous)
{
    ASSERT(isContextThread());
    deleteJSCodeAndGC(synchronous);
    clearDecodedScriptData();
}

void WorkerGlobalScope::deleteJSCodeAndGC(Synchronous synchronous)
{
    ASSERT(isContextThread());

    JSC::JSLockHolder lock(vm());
    vm().deleteAllCode(JSC::DeleteAllCodeIfNotCollecting);

    if (synchronous == Synchronous::Yes) {
        if (!vm().heap.currentThreadIsDoingGCWork()) {
            vm().heap.collectNow(JSC::Sync, JSC::CollectionScope::Full);
            WTF::releaseFastMallocFreeMemory();
            return;
        }
    }
#if PLATFORM(IOS_FAMILY)
    if (!vm().heap.currentThreadIsDoingGCWork()) {
        vm().heap.collectNowFullIfNotDoneRecently(JSC::Async);
        return;
    }
#endif
#if USE(CF) || USE(GLIB)
    vm().heap.reportAbandonedObjectGraph();
#else
    vm().heap.collectNow(JSC::Async, JSC::CollectionScope::Full);
#endif
}

void WorkerGlobalScope::releaseMemoryInWorkers(Synchronous synchronous)
{
    Locker locker { allWorkerGlobalScopeIdentifiersLock };
    for (auto& globalScopeIdentifier : allWorkerGlobalScopeIdentifiers()) {
        postTaskTo(globalScopeIdentifier, [synchronous](auto& context) {
            downcast<WorkerGlobalScope>(context).releaseMemory(synchronous);
        });
    }
}

void WorkerGlobalScope::setMainScriptSourceProvider(ScriptBufferSourceProvider& provider)
{
    ASSERT(!m_mainScriptSourceProvider);
    m_mainScriptSourceProvider = provider;
}

void WorkerGlobalScope::addImportedScriptSourceProvider(const URL& url, ScriptBufferSourceProvider& provider)
{
    m_importedScriptsSourceProviders.ensure(url, [] {
        return WeakHashSet<ScriptBufferSourceProvider> { };
    }).iterator->value.add(provider);
}

void WorkerGlobalScope::clearDecodedScriptData()
{
    ASSERT(isContextThread());

    if (m_mainScriptSourceProvider)
        m_mainScriptSourceProvider->clearDecodedData();

    for (auto& sourceProviders : m_importedScriptsSourceProviders.values()) {
        for (auto& sourceProvider : sourceProviders)
            sourceProvider.clearDecodedData();
    }
}

bool WorkerGlobalScope::crossOriginIsolated() const
{
    return ScriptExecutionContext::crossOriginMode() == CrossOriginMode::Isolated;
}

void WorkerGlobalScope::updateSourceProviderBuffers(const ScriptBuffer& mainScript, const HashMap<URL, ScriptBuffer>& importedScripts)
{
    ASSERT(isContextThread());

    if (mainScript && m_mainScriptSourceProvider)
        m_mainScriptSourceProvider->tryReplaceScriptBuffer(mainScript);

    for (auto& pair : importedScripts) {
        auto it = m_importedScriptsSourceProviders.find(pair.key);
        if (it == m_importedScriptsSourceProviders.end())
            continue;
        for (auto& sourceProvider : it->value)
            sourceProvider.tryReplaceScriptBuffer(pair.value);
    }
}

#if ENABLE(SERVICE_WORKER)
void WorkerGlobalScope::updateServiceWorkerClientData()
{
    if (!settingsValues().serviceWorkersEnabled)
        return;

    ASSERT(type() == WebCore::WorkerGlobalScope::Type::DedicatedWorker || type() == WebCore::WorkerGlobalScope::Type::SharedWorker);
    auto controllingServiceWorkerRegistrationIdentifier = activeServiceWorker() ? std::make_optional<ServiceWorkerRegistrationIdentifier>(activeServiceWorker()->registrationIdentifier()) : std::nullopt;
    swClientConnection().registerServiceWorkerClient(clientOrigin(), ServiceWorkerClientData::from(*this), controllingServiceWorkerRegistrationIdentifier, String { m_userAgent });
}
#endif

} // namespace WebCore
