/*
 * Copyright (C) 2008-2022 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.
 *
 */

#include "config.h"
#include "JSDOMGlobalObject.h"

#include "DOMConstructors.h"
#include "DOMWindow.h"
#include "Document.h"
#include "FetchResponse.h"
#include "FrameDestructionObserverInlines.h"
#include "JSAbortAlgorithm.h"
#include "JSAbortSignal.h"
#include "JSDOMPromiseDeferred.h"
#include "JSDOMWindow.h"
#include "JSEventListener.h"
#include "JSFetchResponse.h"
#include "JSIDBSerializationGlobalObject.h"
#include "JSMediaStream.h"
#include "JSMediaStreamTrack.h"
#include "JSRTCIceCandidate.h"
#include "JSRTCSessionDescription.h"
#include "JSReadableStream.h"
#include "JSRemoteDOMWindow.h"
#include "JSShadowRealmGlobalScope.h"
#include "JSShadowRealmGlobalScopeBase.h"
#include "JSWorkerGlobalScope.h"
#include "JSWorkletGlobalScope.h"
#include "JSWritableStream.h"
#include "RejectedPromiseTracker.h"
#include "RuntimeEnabledFeatures.h"
#include "ScriptController.h"
#include "ScriptModuleLoader.h"
#include "ShadowRealmGlobalScope.h"
#include "StructuredClone.h"
#include "WebCoreJSClientData.h"
#include "WorkerGlobalScope.h"
#include "WorkletGlobalScope.h"
#include <JavaScriptCore/BuiltinNames.h>
#include <JavaScriptCore/CodeBlock.h>
#include <JavaScriptCore/GetterSetter.h>
#include <JavaScriptCore/JSCustomGetterFunction.h>
#include <JavaScriptCore/JSCustomSetterFunction.h>
#include <JavaScriptCore/JSInternalPromise.h>
#include <JavaScriptCore/StructureInlines.h>
#include <JavaScriptCore/VMEntryScope.h>
#include <JavaScriptCore/VMTrapsInlines.h>
#include <JavaScriptCore/WasmStreamingCompiler.h>
#include <JavaScriptCore/WeakGCMapInlines.h>

namespace WebCore {
using namespace JSC;

JSC_DECLARE_HOST_FUNCTION(makeThisTypeErrorForBuiltins);
JSC_DECLARE_HOST_FUNCTION(makeGetterTypeErrorForBuiltins);
JSC_DECLARE_HOST_FUNCTION(makeDOMExceptionForBuiltins);
JSC_DECLARE_HOST_FUNCTION(isReadableByteStreamAPIEnabled);
JSC_DECLARE_HOST_FUNCTION(createWritableStreamFromInternal);
JSC_DECLARE_HOST_FUNCTION(getInternalWritableStream);
JSC_DECLARE_HOST_FUNCTION(whenSignalAborted);
JSC_DECLARE_HOST_FUNCTION(isAbortSignal);

const ClassInfo JSDOMGlobalObject::s_info = { "DOMGlobalObject"_s, &JSGlobalObject::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSDOMGlobalObject) };

JSDOMGlobalObject::JSDOMGlobalObject(VM& vm, Structure* structure, Ref<DOMWrapperWorld>&& world, const GlobalObjectMethodTable* globalObjectMethodTable)
    : JSGlobalObject(vm, structure, globalObjectMethodTable)
    , m_constructors(makeUnique<DOMConstructors>())
    , m_world(WTFMove(world))
    , m_worldIsNormal(m_world->isNormal())
    , m_builtinInternalFunctions(vm)
    , m_crossOriginFunctionMap(vm)
    , m_crossOriginGetterSetterMap(vm)
{
}

JSDOMGlobalObject::~JSDOMGlobalObject() = default;

void JSDOMGlobalObject::destroy(JSCell* cell)
{
    static_cast<JSDOMGlobalObject*>(cell)->JSDOMGlobalObject::~JSDOMGlobalObject();
}

JSC_DEFINE_HOST_FUNCTION(makeThisTypeErrorForBuiltins, (JSGlobalObject* globalObject, CallFrame* callFrame))
{
    ASSERT(callFrame);
    ASSERT(callFrame->argumentCount() == 2);
    VM& vm = globalObject->vm();
    DeferTermination deferScope(vm);
    auto scope = DECLARE_CATCH_SCOPE(vm);

    auto interfaceName = callFrame->uncheckedArgument(0).getString(globalObject);
    scope.assertNoException();
    auto functionName = callFrame->uncheckedArgument(1).getString(globalObject);
    scope.assertNoException();
    return JSValue::encode(createTypeError(globalObject, makeThisTypeErrorMessage(interfaceName.utf8().data(), functionName.utf8().data())));
}

JSC_DEFINE_HOST_FUNCTION(makeGetterTypeErrorForBuiltins, (JSGlobalObject* globalObject, CallFrame* callFrame))
{
    ASSERT(callFrame);
    ASSERT(callFrame->argumentCount() == 2);
    VM& vm = globalObject->vm();
    DeferTermination deferScope(vm);
    auto scope = DECLARE_CATCH_SCOPE(vm);

    auto interfaceName = callFrame->uncheckedArgument(0).getString(globalObject);
    scope.assertNoException();
    auto attributeName = callFrame->uncheckedArgument(1).getString(globalObject);
    scope.assertNoException();

    auto error = static_cast<ErrorInstance*>(createTypeError(globalObject, JSC::makeDOMAttributeGetterTypeErrorMessage(interfaceName.utf8().data(), attributeName)));
    error->setNativeGetterTypeError();
    return JSValue::encode(error);
}

JSC_DEFINE_HOST_FUNCTION(makeDOMExceptionForBuiltins, (JSGlobalObject* globalObject, CallFrame* callFrame))
{
    ASSERT(callFrame);
    ASSERT(callFrame->argumentCount() == 2);

    auto& vm = globalObject->vm();
    DeferTermination deferScope(vm);
    auto scope = DECLARE_CATCH_SCOPE(vm);

    auto codeValue = callFrame->uncheckedArgument(0).getString(globalObject);
    scope.assertNoException();

    auto message = callFrame->uncheckedArgument(1).getString(globalObject);
    scope.assertNoException();

    ExceptionCode code { TypeError };
    if (codeValue == "AbortError"_s)
        code = AbortError;
    auto value = createDOMException(globalObject, code, message);

    EXCEPTION_ASSERT(!scope.exception() || vm.hasPendingTerminationException());

    return JSValue::encode(value);
}

JSC_DEFINE_HOST_FUNCTION(isReadableByteStreamAPIEnabled, (JSGlobalObject*, CallFrame*))
{
    return JSValue::encode(jsBoolean(RuntimeEnabledFeatures::sharedFeatures().readableByteStreamAPIEnabled()));
}

JSC_DEFINE_HOST_FUNCTION(getInternalWritableStream, (JSGlobalObject*, CallFrame* callFrame))
{
    ASSERT(callFrame);
    ASSERT(callFrame->argumentCount() == 1);

    auto* writableStream = jsDynamicCast<JSWritableStream*>(callFrame->uncheckedArgument(0));
    if (UNLIKELY(!writableStream))
        return JSValue::encode(jsUndefined());
    return JSValue::encode(writableStream->wrapped().internalWritableStream());
}

JSC_DEFINE_HOST_FUNCTION(createWritableStreamFromInternal, (JSGlobalObject* globalObject, CallFrame* callFrame))
{
    ASSERT(callFrame);
    ASSERT(callFrame->argumentCount() == 1);
    ASSERT(callFrame->uncheckedArgument(0).isObject());

    auto* jsDOMGlobalObject = JSC::jsCast<JSDOMGlobalObject*>(globalObject);
    auto internalWritableStream = InternalWritableStream::fromObject(*jsDOMGlobalObject, *callFrame->uncheckedArgument(0).toObject(globalObject));
    return JSValue::encode(toJSNewlyCreated(globalObject, jsDOMGlobalObject, WritableStream::create(WTFMove(internalWritableStream))));
}

JSC_DEFINE_HOST_FUNCTION(whenSignalAborted, (JSGlobalObject* globalObject, CallFrame* callFrame))
{
    ASSERT(callFrame);
    ASSERT(callFrame->argumentCount() == 2);

    auto* abortSignal = jsDynamicCast<JSAbortSignal*>(callFrame->uncheckedArgument(0));
    if (UNLIKELY(!abortSignal))
        return JSValue::encode(JSValue(JSC::JSValue::JSFalse));

    auto* jsDOMGlobalObject = JSC::jsCast<JSDOMGlobalObject*>(globalObject);
    Ref<AbortAlgorithm> abortAlgorithm = JSAbortAlgorithm::create(callFrame->uncheckedArgument(1).getObject(), jsDOMGlobalObject);

    bool result = AbortSignal::whenSignalAborted(abortSignal->wrapped(), WTFMove(abortAlgorithm));
    return JSValue::encode(result ? JSValue(JSC::JSValue::JSTrue) : JSValue(JSC::JSValue::JSFalse));
}

JSC_DEFINE_HOST_FUNCTION(isAbortSignal, (JSGlobalObject*, CallFrame* callFrame))
{
    ASSERT(callFrame->argumentCount() == 1);
    return JSValue::encode(jsBoolean(callFrame->uncheckedArgument(0).inherits<JSAbortSignal>()));
}

SUPPRESS_ASAN void JSDOMGlobalObject::addBuiltinGlobals(VM& vm)
{
    m_builtinInternalFunctions.initialize(*this);

    auto& builtinNames = WebCore::builtinNames(vm);
    JSDOMGlobalObject::GlobalPropertyInfo staticGlobals[] = {
        JSDOMGlobalObject::GlobalPropertyInfo(builtinNames.makeThisTypeErrorPrivateName(),
            JSFunction::create(vm, this, 2, String(), makeThisTypeErrorForBuiltins), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
        JSDOMGlobalObject::GlobalPropertyInfo(builtinNames.makeGetterTypeErrorPrivateName(),
            JSFunction::create(vm, this, 2, String(), makeGetterTypeErrorForBuiltins), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
        JSDOMGlobalObject::GlobalPropertyInfo(builtinNames.makeDOMExceptionPrivateName(),
            JSFunction::create(vm, this, 2, String(), makeDOMExceptionForBuiltins), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
        JSDOMGlobalObject::GlobalPropertyInfo(builtinNames.whenSignalAbortedPrivateName(),
            JSFunction::create(vm, this, 2, String(), whenSignalAborted), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
        JSDOMGlobalObject::GlobalPropertyInfo(builtinNames.cloneArrayBufferPrivateName(),
            JSFunction::create(vm, this, 3, String(), cloneArrayBuffer), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
        JSDOMGlobalObject::GlobalPropertyInfo(builtinNames.structuredCloneForStreamPrivateName(),
            JSFunction::create(vm, this, 1, String(), structuredCloneForStream), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
        JSDOMGlobalObject::GlobalPropertyInfo(vm.propertyNames->builtinNames().ArrayBufferPrivateName(), arrayBufferConstructor(), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
        JSDOMGlobalObject::GlobalPropertyInfo(builtinNames.streamClosedPrivateName(), jsNumber(1), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
        JSDOMGlobalObject::GlobalPropertyInfo(builtinNames.streamClosingPrivateName(), jsNumber(2), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
        JSDOMGlobalObject::GlobalPropertyInfo(builtinNames.streamErroredPrivateName(), jsNumber(3), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
        JSDOMGlobalObject::GlobalPropertyInfo(builtinNames.streamReadablePrivateName(), jsNumber(4), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
        JSDOMGlobalObject::GlobalPropertyInfo(builtinNames.streamWaitingPrivateName(), jsNumber(5), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
        JSDOMGlobalObject::GlobalPropertyInfo(builtinNames.streamWritablePrivateName(), jsNumber(6), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
        JSDOMGlobalObject::GlobalPropertyInfo(builtinNames.readableByteStreamAPIEnabledPrivateName(), JSFunction::create(vm, this, 0, String(), isReadableByteStreamAPIEnabled), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
        JSDOMGlobalObject::GlobalPropertyInfo(builtinNames.isAbortSignalPrivateName(), JSFunction::create(vm, this, 1, String(), isAbortSignal), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
        JSDOMGlobalObject::GlobalPropertyInfo(builtinNames.getInternalWritableStreamPrivateName(), JSFunction::create(vm, this, 1, String(), getInternalWritableStream), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
        JSDOMGlobalObject::GlobalPropertyInfo(builtinNames.createWritableStreamFromInternalPrivateName(), JSFunction::create(vm, this, 1, String(), createWritableStreamFromInternal), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
    };
    addStaticGlobals(staticGlobals, WTF_ARRAY_LENGTH(staticGlobals));
}

void JSDOMGlobalObject::finishCreation(VM& vm)
{
    Base::finishCreation(vm);
    ASSERT(inherits(info()));

    addBuiltinGlobals(vm);

    RELEASE_ASSERT(classInfo());
}

void JSDOMGlobalObject::finishCreation(VM& vm, JSObject* thisValue)
{
    Base::finishCreation(vm, thisValue);
    ASSERT(inherits(info()));

    addBuiltinGlobals(vm);

    RELEASE_ASSERT(classInfo());
}

ScriptExecutionContext* JSDOMGlobalObject::scriptExecutionContext() const
{
    if (inherits<JSDOMWindowBase>())
        return jsCast<const JSDOMWindowBase*>(this)->scriptExecutionContext();
    if (inherits<JSRemoteDOMWindowBase>())
        return nullptr;
    if (inherits<JSShadowRealmGlobalScopeBase>())
        return jsCast<const JSShadowRealmGlobalScopeBase*>(this)->scriptExecutionContext();
    if (inherits<JSWorkerGlobalScopeBase>())
        return jsCast<const JSWorkerGlobalScopeBase*>(this)->scriptExecutionContext();
    if (inherits<JSWorkletGlobalScopeBase>())
        return jsCast<const JSWorkletGlobalScopeBase*>(this)->scriptExecutionContext();
    if (inherits<JSIDBSerializationGlobalObject>())
        return jsCast<const JSIDBSerializationGlobalObject*>(this)->scriptExecutionContext();

    dataLog("Unexpected global object: ", JSValue(this), "\n");
    RELEASE_ASSERT_NOT_REACHED();
    return nullptr;
}

template<typename Visitor>
void JSDOMGlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor)
{
    JSDOMGlobalObject* thisObject = jsCast<JSDOMGlobalObject*>(cell);
    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
    Base::visitChildren(thisObject, visitor);

    {
        // The GC thread has to grab the GC lock even though it is not mutating the containers.
        Locker locker { thisObject->m_gcLock };

        for (auto& structure : thisObject->m_structures.values())
            visitor.append(structure);

        for (auto& guarded : thisObject->m_guardedObjects)
            guarded->visitAggregate(visitor);
    }

    for (auto& constructor : thisObject->constructors().array())
        visitor.append(constructor);

    thisObject->m_builtinInternalFunctions.visit(visitor);
}

DEFINE_VISIT_CHILDREN(JSDOMGlobalObject);

void JSDOMGlobalObject::promiseRejectionTracker(JSGlobalObject* jsGlobalObject, JSPromise* promise, JSPromiseRejectionOperation operation)
{
    // https://html.spec.whatwg.org/multipage/webappapis.html#the-hostpromiserejectiontracker-implementation

    auto& globalObject = *JSC::jsCast<JSDOMGlobalObject*>(jsGlobalObject);
    auto* context = globalObject.scriptExecutionContext();
    if (!context)
        return;

    auto rejectedPromiseTracker = context->ensureRejectedPromiseTracker();
    if (!rejectedPromiseTracker)
        return;

    // FIXME: If script has muted errors (cross origin), terminate these steps.
    // <https://webkit.org/b/171415> Implement the `muted-errors` property of Scripts to avoid onerror/onunhandledrejection for cross-origin scripts

    switch (operation) {
    case JSPromiseRejectionOperation::Reject:
        rejectedPromiseTracker->promiseRejected(globalObject, *promise);
        break;
    case JSPromiseRejectionOperation::Handle:
        rejectedPromiseTracker->promiseHandled(globalObject, *promise);
        break;
    }
}

void JSDOMGlobalObject::reportUncaughtExceptionAtEventLoop(JSGlobalObject* jsGlobalObject, JSC::Exception* exception)
{
    reportException(jsGlobalObject, exception);
}

void JSDOMGlobalObject::clearDOMGuardedObjects() const
{
    // No locking is necessary here since we are not directly modifying the returned container.
    // Calling JSDOMGuardedObject::clear() will however modify the guarded objects container but
    // it will grab the lock as needed.
    auto guardedObjectsCopy = guardedObjects();
    for (auto& guarded : guardedObjectsCopy)
        guarded->clear();
}

JSFunction* JSDOMGlobalObject::createCrossOriginFunction(JSGlobalObject* lexicalGlobalObject, PropertyName propertyName, NativeFunction nativeFunction, unsigned length)
{
    auto& vm = lexicalGlobalObject->vm();
    CrossOriginMapKey key = std::make_pair(lexicalGlobalObject, nativeFunction.rawPointer());

    // WeakGCMap::ensureValue's functor must not invoke GC since GC can modify WeakGCMap in the middle of HashMap::ensure.
    // We use DeferGC here (1) not to invoke GC when executing WeakGCMap::ensureValue and (2) to avoid looking up HashMap twice.
    DeferGC deferGC(vm);
    return m_crossOriginFunctionMap.ensureValue(key, [&] {
        return JSFunction::create(vm, lexicalGlobalObject, length, propertyName.publicName(), nativeFunction);
    });
}

GetterSetter* JSDOMGlobalObject::createCrossOriginGetterSetter(JSGlobalObject* lexicalGlobalObject, PropertyName propertyName, GetValueFunc getter, PutValueFunc setter)
{
    ASSERT(getter || setter);
    auto& vm = lexicalGlobalObject->vm();
    CrossOriginMapKey key = std::make_pair(lexicalGlobalObject, getter ? reinterpret_cast<void*>(getter) : reinterpret_cast<void*>(setter));

    // WeakGCMap::ensureValue's functor must not invoke GC since GC can modify WeakGCMap in the middle of HashMap::ensure.
    // We use DeferGC here (1) not to invoke GC when executing WeakGCMap::ensureValue and (2) to avoid looking up HashMap twice.
    DeferGC deferGC(vm);
    return m_crossOriginGetterSetterMap.ensureValue(key, [&] {
        return GetterSetter::create(vm, lexicalGlobalObject,
            getter ? JSCustomGetterFunction::create(vm, lexicalGlobalObject, propertyName, getter) : nullptr,
            setter ? JSCustomSetterFunction::create(vm, lexicalGlobalObject, propertyName, setter) : nullptr);
    });
}

#if ENABLE(WEBASSEMBLY)
// https://webassembly.github.io/spec/web-api/index.html#compile-a-potential-webassembly-response
static JSC::JSPromise* handleResponseOnStreamingAction(JSC::JSGlobalObject* globalObject, JSC::JSValue source, JSC::Wasm::CompilerMode compilerMode, JSC::JSObject* importObject)
{
    VM& vm = globalObject->vm();
    JSLockHolder lock(vm);

    auto deferred = DeferredPromise::create(*jsCast<JSDOMGlobalObject*>(globalObject), DeferredPromise::Mode::RetainPromiseOnResolve);

    auto inputResponse = JSFetchResponse::toWrapped(vm, source);
    if (!inputResponse) {
        deferred->reject(TypeError, "first argument must be an Response or Promise for Response"_s);
        return jsCast<JSC::JSPromise*>(deferred->promise());
    }

    if (auto exception = inputResponse->loadingException()) {
        deferred->reject(*exception);
        return jsCast<JSC::JSPromise*>(deferred->promise());
    }

    // 4. If response is not CORS-same-origin, reject returnValue with a TypeError and abort these substeps.
    // If response is opaque, content-type becomes "".
    if (!inputResponse->isCORSSameOrigin()) {
        deferred->reject(TypeError, "Response is not CORS-same-origin"_s);
        return jsCast<JSC::JSPromise*>(deferred->promise());
    }

    // 3. If mimeType is not `application/wasm`, reject returnValue with a TypeError and abort these substeps.
    if (!inputResponse->hasWasmMIMEType()) {
        deferred->reject(TypeError, "Unexpected response MIME type. Expected 'application/wasm'"_s);
        return jsCast<JSC::JSPromise*>(deferred->promise());
    }

    // 5. If response’s status is not an ok status, reject returnValue with a TypeError and abort these substeps.
    if (!inputResponse->ok()) {
        deferred->reject(TypeError, "Response has not returned OK status"_s);
        return jsCast<JSC::JSPromise*>(deferred->promise());
    }

    // https://fetch.spec.whatwg.org/#concept-body-consume-body
    if (inputResponse->isDisturbedOrLocked()) {
        deferred->reject(TypeError, "Response is disturbed or locked"_s);
        return jsCast<JSC::JSPromise*>(deferred->promise());
    }

    // FIXME: for efficiency, we should load blobs directly instead of going through the readableStream path.
    if (inputResponse->isBlobBody()) {
        auto streamOrException = inputResponse->readableStream(*globalObject);
        if (UNLIKELY(streamOrException.hasException())) {
            deferred->reject(streamOrException.releaseException());
            return jsCast<JSC::JSPromise*>(deferred->promise());
        }
    }

    auto compiler = JSC::Wasm::StreamingCompiler::create(vm, compilerMode, globalObject, jsCast<JSC::JSPromise*>(deferred->promise()), importObject);

    if (inputResponse->isBodyReceivedByChunk()) {
        inputResponse->consumeBodyReceivedByChunk([globalObject, compiler = WTFMove(compiler)](auto&& result) mutable {
            VM& vm = globalObject->vm();
            JSLockHolder lock(vm);

            if (result.hasException()) {
                auto exception = result.exception();
                if (exception.code() == ExistingExceptionError) {
                    auto scope = DECLARE_CATCH_SCOPE(vm);

                    EXCEPTION_ASSERT(scope.exception());

                    auto error = scope.exception()->value();
                    scope.clearException();

                    compiler->fail(globalObject, error);
                    return;
                }

                auto scope = DECLARE_THROW_SCOPE(vm);
                auto error = createDOMException(*globalObject, WTFMove(exception));
                if (UNLIKELY(scope.exception())) {
                    ASSERT(vm.hasPendingTerminationException());
                    compiler->cancel();
                    return;
                }

                compiler->fail(globalObject, error);
                return;
            }

            if (auto* chunk = result.returnValue())
                compiler->addBytes(chunk->data(), chunk->size());
            else
                compiler->finalize(globalObject);
        });
        return jsCast<JSC::JSPromise*>(deferred->promise());
    }

    auto body = inputResponse->consumeBody();
    WTF::switchOn(body, [&](Ref<FormData>& formData) {
        if (auto buffer = formData->asSharedBuffer()) {
            compiler->addBytes(buffer->data(), buffer->size());
            compiler->finalize(globalObject);
            return;
        }
        // FIXME: Support FormData loading.
        // https://bugs.webkit.org/show_bug.cgi?id=221248
        compiler->fail(globalObject, createDOMException(*globalObject, Exception { NotSupportedError, "Not implemented"_s  }));
    }, [&](Ref<SharedBuffer>& buffer) {
        compiler->addBytes(buffer->data(), buffer->size());
        compiler->finalize(globalObject);
    }, [&](std::nullptr_t&) {
        compiler->finalize(globalObject);
    });

    return jsCast<JSC::JSPromise*>(deferred->promise());
}

JSC::JSPromise* JSDOMGlobalObject::compileStreaming(JSC::JSGlobalObject* globalObject, JSC::JSValue source)
{
    ASSERT(source);
    return handleResponseOnStreamingAction(globalObject, source, JSC::Wasm::CompilerMode::Validation, nullptr);
}

JSC::JSPromise* JSDOMGlobalObject::instantiateStreaming(JSC::JSGlobalObject* globalObject, JSC::JSValue source, JSC::JSObject* importObject)
{
    ASSERT(source);
    return handleResponseOnStreamingAction(globalObject, source, JSC::Wasm::CompilerMode::FullCompile, importObject);
}
#endif

static ScriptModuleLoader* scriptModuleLoader(JSDOMGlobalObject* globalObject)
{
    if (globalObject->inherits<JSDOMWindowBase>()) {
        if (auto document = jsCast<const JSDOMWindowBase*>(globalObject)->wrapped().document())
            return &document->moduleLoader();
        return nullptr;
    }
    if (globalObject->inherits<JSShadowRealmGlobalScopeBase>())
        return &jsCast<const JSShadowRealmGlobalScopeBase*>(globalObject)->wrapped().moduleLoader();
    if (globalObject->inherits<JSRemoteDOMWindowBase>())
        return nullptr;
    if (globalObject->inherits<JSWorkerGlobalScopeBase>())
        return &jsCast<const JSWorkerGlobalScopeBase*>(globalObject)->wrapped().moduleLoader();
    if (globalObject->inherits<JSWorkletGlobalScopeBase>())
        return &jsCast<const JSWorkletGlobalScopeBase*>(globalObject)->wrapped().moduleLoader();
    if (globalObject->inherits<JSIDBSerializationGlobalObject>())
        return nullptr;

    dataLog("Unexpected global object: ", JSValue(globalObject), "\n");
    RELEASE_ASSERT_NOT_REACHED();
    return nullptr;
}

JSC::Identifier JSDOMGlobalObject::moduleLoaderResolve(JSC::JSGlobalObject* globalObject, JSC::JSModuleLoader* moduleLoader, JSC::JSValue moduleName, JSC::JSValue importerModuleKey, JSC::JSValue scriptFetcher)
{
    JSDOMGlobalObject* thisObject = JSC::jsCast<JSDOMGlobalObject*>(globalObject);
    if (auto* loader = scriptModuleLoader(thisObject))
        return loader->resolve(globalObject, moduleLoader, moduleName, importerModuleKey, scriptFetcher);
    return { };
}

JSC::JSInternalPromise* JSDOMGlobalObject::moduleLoaderFetch(JSC::JSGlobalObject* globalObject, JSC::JSModuleLoader* moduleLoader, JSC::JSValue moduleKey, JSC::JSValue parameters, JSC::JSValue scriptFetcher)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);
    JSDOMGlobalObject* thisObject = JSC::jsCast<JSDOMGlobalObject*>(globalObject);
    if (auto* loader = scriptModuleLoader(thisObject))
        RELEASE_AND_RETURN(scope, loader->fetch(globalObject, moduleLoader, moduleKey, parameters, scriptFetcher));
    JSC::JSInternalPromise* promise = JSC::JSInternalPromise::create(vm, globalObject->internalPromiseStructure());
    scope.release();
    promise->reject(globalObject, jsUndefined());
    return promise;
}

JSC::JSValue JSDOMGlobalObject::moduleLoaderEvaluate(JSC::JSGlobalObject* globalObject, JSC::JSModuleLoader* moduleLoader, JSC::JSValue moduleKey, JSC::JSValue moduleRecord, JSC::JSValue scriptFetcher, JSC::JSValue awaitedValue, JSC::JSValue resumeMode)
{
    JSDOMGlobalObject* thisObject = JSC::jsCast<JSDOMGlobalObject*>(globalObject);
    if (auto* loader = scriptModuleLoader(thisObject))
        return loader->evaluate(globalObject, moduleLoader, moduleKey, moduleRecord, scriptFetcher, awaitedValue, resumeMode);
    return JSC::jsUndefined();
}

JSC::JSInternalPromise* JSDOMGlobalObject::moduleLoaderImportModule(JSC::JSGlobalObject* globalObject, JSC::JSModuleLoader* moduleLoader, JSC::JSString* moduleName, JSC::JSValue parameters, const JSC::SourceOrigin& sourceOrigin)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);
    JSDOMGlobalObject* thisObject = JSC::jsCast<JSDOMGlobalObject*>(globalObject);
    if (auto* loader = scriptModuleLoader(thisObject))
        RELEASE_AND_RETURN(scope, loader->importModule(globalObject, moduleLoader, moduleName, parameters, sourceOrigin));
    JSC::JSInternalPromise* promise = JSC::JSInternalPromise::create(vm, globalObject->internalPromiseStructure());
    scope.release();
    promise->reject(globalObject, jsUndefined());
    return promise;
}

JSC::JSObject* JSDOMGlobalObject::moduleLoaderCreateImportMetaProperties(JSC::JSGlobalObject* globalObject, JSC::JSModuleLoader* moduleLoader, JSC::JSValue moduleKey, JSC::JSModuleRecord* moduleRecord, JSC::JSValue scriptFetcher)
{
    JSDOMGlobalObject* thisObject = JSC::jsCast<JSDOMGlobalObject*>(globalObject);
    if (auto* loader = scriptModuleLoader(thisObject))
        return loader->createImportMetaProperties(globalObject, moduleLoader, moduleKey, moduleRecord, scriptFetcher);
    return constructEmptyObject(globalObject->vm(), globalObject->nullPrototypeObjectStructure());
}

JSC::JSGlobalObject* JSDOMGlobalObject::deriveShadowRealmGlobalObject(JSC::JSGlobalObject* globalObject)
{
    auto& vm = globalObject->vm();

    auto domGlobalObject = jsCast<JSDOMGlobalObject*>(globalObject);
    auto context = domGlobalObject->scriptExecutionContext();
    if (is<Document>(context)) {
        // Same-origin iframes present a difficult circumstance because the
        // shadow realm global object cannot retain the incubating realm's
        // global object (that would be a refcount loop); but, same-origin
        // iframes can create objects that outlive their global object.
        //
        // Our solution is to walk up the parent tree of documents as far as
        // possible while still staying in the same origin to insure we don't
        // allow the ShadowRealm to fetch modules masquerading as the wrong
        // origin while avoiding any lifetime issues (since the topmost document
        // with a given wrapper world should outlive other objects in that
        // world)
        auto document = &downcast<Document>(*context);
        auto const& originalOrigin = document->securityOrigin();
        auto& originalWorld = domGlobalObject->world();

        while (!document->isTopDocument()) {
            auto candidateDocument = document->parentDocument();

            if (!candidateDocument->securityOrigin().isSameOriginDomain(originalOrigin))
                break;

            document = candidateDocument;
            domGlobalObject = candidateDocument->frame()->script().globalObject(originalWorld);
        }
    }

    ASSERT(domGlobalObject);
    auto scope = ShadowRealmGlobalScope::create(domGlobalObject, scriptModuleLoader(domGlobalObject));

    auto structure = JSShadowRealmGlobalScope::createStructure(vm, nullptr, JSC::jsNull());
    auto proxyStructure = JSProxy::createStructure(vm, nullptr, JSC::jsNull());
    auto proxy = JSProxy::create(vm, proxyStructure);
    auto wrapper = JSShadowRealmGlobalScope::create(vm, structure, WTFMove(scope), proxy);

    wrapper->setPrototypeDirect(vm, wrapper->objectPrototype());
    proxy->setTarget(vm, wrapper);

    wrapper->setConsoleClient(domGlobalObject->consoleClient());

    return wrapper;
}


JSDOMGlobalObject* toJSDOMGlobalObject(ScriptExecutionContext& context, DOMWrapperWorld& world)
{
    if (is<Document>(context))
        return toJSDOMWindow(downcast<Document>(context).frame(), world);

    if (is<WorkerOrWorkletGlobalScope>(context))
        return downcast<WorkerOrWorkletGlobalScope>(context).script()->globalScopeWrapper();

    ASSERT_NOT_REACHED();
    return nullptr;
}

static JSDOMGlobalObject& callerGlobalObject(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame* callFrame, bool skipFirstFrame, bool lookUpFromVMEntryScope)
{
    VM& vm = lexicalGlobalObject.vm();
    if (callFrame) {
        class GetCallerGlobalObjectFunctor {
        public:
            GetCallerGlobalObjectFunctor(bool skipFirstFrame)
                : m_skipFirstFrame(skipFirstFrame)
            { }

            IterationStatus operator()(StackVisitor& visitor) const
            {
                if (m_skipFirstFrame) {
                    if (!m_hasSkippedFirstFrame) {
                        m_hasSkippedFirstFrame = true;
                        return IterationStatus::Continue;
                    }
                }

                if (auto* codeBlock = visitor->codeBlock())
                    m_globalObject = codeBlock->globalObject();
                else {
                    ASSERT(visitor->callee().rawPtr());
                    // FIXME: Callee is not an object if the caller is Web Assembly.
                    // Figure out what to do here. We can probably get the global object
                    // from the top-most Wasm Instance. https://bugs.webkit.org/show_bug.cgi?id=165721
                    if (visitor->callee().isCell() && visitor->callee().asCell()->isObject())
                        m_globalObject = jsCast<JSObject*>(visitor->callee().asCell())->globalObject();
                }
                return IterationStatus::Done;
            }

            JSC::JSGlobalObject* globalObject() const { return m_globalObject; }

        private:
            bool m_skipFirstFrame { false };
            mutable bool m_hasSkippedFirstFrame { false };
            mutable JSC::JSGlobalObject* m_globalObject { nullptr };
        };

        GetCallerGlobalObjectFunctor iter(skipFirstFrame);
        callFrame->iterate(vm, iter);
        if (iter.globalObject())
            return *jsCast<JSDOMGlobalObject*>(iter.globalObject());
    }

    // In the case of legacyActiveGlobalObjectForAccessor, it is possible that vm.topCallFrame is nullptr when the script is evaluated as JSONP.
    // Since we put JSGlobalObject to VMEntryScope, we can retrieve the right globalObject from that.
    // For callerGlobalObject, we do not check vm.entryScope to keep it the old behavior.
    if (lookUpFromVMEntryScope) {
        if (vm.entryScope) {
            if (auto* result = vm.entryScope->globalObject())
                return *jsCast<JSDOMGlobalObject*>(result);
        }
    }

    // If we cannot find JSGlobalObject in caller frames, we just return the current lexicalGlobalObject.
    return *jsCast<JSDOMGlobalObject*>(&lexicalGlobalObject);
}

JSDOMGlobalObject& callerGlobalObject(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame* callFrame)
{
    constexpr bool skipFirstFrame = true;
    constexpr bool lookUpFromVMEntryScope = false;
    return callerGlobalObject(lexicalGlobalObject, callFrame, skipFirstFrame, lookUpFromVMEntryScope);
}

JSDOMGlobalObject& legacyActiveGlobalObjectForAccessor(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame* callFrame)
{
    constexpr bool skipFirstFrame = false;
    constexpr bool lookUpFromVMEntryScope = true;
    return callerGlobalObject(lexicalGlobalObject, callFrame, skipFirstFrame, lookUpFromVMEntryScope);
}

} // namespace WebCore
