/*
    This file is part of the WebKit open source project.
    This file has been generated by generate-bindings.pl. DO NOT MODIFY!

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include "config.h"

#if ENABLE(FETCH_API)

#include "JSFetchRequest.h"

#include "Dictionary.h"
#include "ExceptionCode.h"
#include "FetchHeaders.h"
#include "FetchRequest.h"
#include "FetchRequestBuiltins.h"
#include "JSDOMBinding.h"
#include "JSDOMConstructor.h"
#include "JSDOMConvert.h"
#include "JSDOMPromise.h"
#include "JSFetchHeaders.h"
#include "JSFetchRequest.h"
#include "RuntimeEnabledFeatures.h"
#include "URL.h"
#include "WebCoreJSClientData.h"
#include <runtime/Error.h>
#include <runtime/FunctionPrototype.h>
#include <runtime/JSString.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

template<typename T> Optional<T> parse(ExecState&, JSValue);
template<typename T> const char* expectedEnumerationValues();

JSString* jsStringWithCache(ExecState*, FetchRequest::Type);

JSString* jsStringWithCache(ExecState* state, FetchRequest::Type enumerationValue)
{
    static NeverDestroyed<const String> values[] = {
        emptyString(),
        ASCIILiteral("audio"),
        ASCIILiteral("font"),
        ASCIILiteral("image"),
        ASCIILiteral("script"),
        ASCIILiteral("style"),
        ASCIILiteral("track"),
        ASCIILiteral("video"),
    };
    static_assert(static_cast<size_t>(FetchRequest::Type::EmptyString) == 0, "FetchRequest::Type::EmptyString is not 0 as expected");
    static_assert(static_cast<size_t>(FetchRequest::Type::Audio) == 1, "FetchRequest::Type::Audio is not 1 as expected");
    static_assert(static_cast<size_t>(FetchRequest::Type::Font) == 2, "FetchRequest::Type::Font is not 2 as expected");
    static_assert(static_cast<size_t>(FetchRequest::Type::Image) == 3, "FetchRequest::Type::Image is not 3 as expected");
    static_assert(static_cast<size_t>(FetchRequest::Type::Script) == 4, "FetchRequest::Type::Script is not 4 as expected");
    static_assert(static_cast<size_t>(FetchRequest::Type::Style) == 5, "FetchRequest::Type::Style is not 5 as expected");
    static_assert(static_cast<size_t>(FetchRequest::Type::Track) == 6, "FetchRequest::Type::Track is not 6 as expected");
    static_assert(static_cast<size_t>(FetchRequest::Type::Video) == 7, "FetchRequest::Type::Video is not 7 as expected");
    ASSERT(static_cast<size_t>(enumerationValue) < WTF_ARRAY_LENGTH(values));
    return jsStringWithCache(state, values[static_cast<size_t>(enumerationValue)]);
}

template<> struct JSValueTraits<FetchRequest::Type> {
    static JSString* arrayJSValue(ExecState* state, JSDOMGlobalObject*, FetchRequest::Type value) { return jsStringWithCache(state, value); }
};

template<> Optional<FetchRequest::Type> parse<FetchRequest::Type>(ExecState& state, JSValue value)
{
    auto stringValue = value.toWTFString(&state);
    if (stringValue.isEmpty())
        return FetchRequest::Type::EmptyString;
    if (stringValue == "audio")
        return FetchRequest::Type::Audio;
    if (stringValue == "font")
        return FetchRequest::Type::Font;
    if (stringValue == "image")
        return FetchRequest::Type::Image;
    if (stringValue == "script")
        return FetchRequest::Type::Script;
    if (stringValue == "style")
        return FetchRequest::Type::Style;
    if (stringValue == "track")
        return FetchRequest::Type::Track;
    if (stringValue == "video")
        return FetchRequest::Type::Video;
    return Nullopt;
}

template<> FetchRequest::Type convert<FetchRequest::Type>(ExecState& state, JSValue value)
{
    VM& vm = state.vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    auto result = parse<FetchRequest::Type>(state, value);
    if (UNLIKELY(!result)) {
        throwTypeError(&state, throwScope);
        return { };
    }
    return result.value();
}

template<> inline const char* expectedEnumerationValues<FetchRequest::Type>()
{
    return "\"\", \"audio\", \"font\", \"image\", \"script\", \"style\", \"track\", \"video\"";
}

JSString* jsStringWithCache(ExecState*, FetchRequest::Destination);

JSString* jsStringWithCache(ExecState* state, FetchRequest::Destination enumerationValue)
{
    static NeverDestroyed<const String> values[] = {
        emptyString(),
        ASCIILiteral("document"),
        ASCIILiteral("sharedworker"),
        ASCIILiteral("subresource"),
        ASCIILiteral("unknown"),
        ASCIILiteral("worker"),
    };
    static_assert(static_cast<size_t>(FetchRequest::Destination::EmptyString) == 0, "FetchRequest::Destination::EmptyString is not 0 as expected");
    static_assert(static_cast<size_t>(FetchRequest::Destination::Document) == 1, "FetchRequest::Destination::Document is not 1 as expected");
    static_assert(static_cast<size_t>(FetchRequest::Destination::Sharedworker) == 2, "FetchRequest::Destination::Sharedworker is not 2 as expected");
    static_assert(static_cast<size_t>(FetchRequest::Destination::Subresource) == 3, "FetchRequest::Destination::Subresource is not 3 as expected");
    static_assert(static_cast<size_t>(FetchRequest::Destination::Unknown) == 4, "FetchRequest::Destination::Unknown is not 4 as expected");
    static_assert(static_cast<size_t>(FetchRequest::Destination::Worker) == 5, "FetchRequest::Destination::Worker is not 5 as expected");
    ASSERT(static_cast<size_t>(enumerationValue) < WTF_ARRAY_LENGTH(values));
    return jsStringWithCache(state, values[static_cast<size_t>(enumerationValue)]);
}

template<> struct JSValueTraits<FetchRequest::Destination> {
    static JSString* arrayJSValue(ExecState* state, JSDOMGlobalObject*, FetchRequest::Destination value) { return jsStringWithCache(state, value); }
};

template<> Optional<FetchRequest::Destination> parse<FetchRequest::Destination>(ExecState& state, JSValue value)
{
    auto stringValue = value.toWTFString(&state);
    if (stringValue.isEmpty())
        return FetchRequest::Destination::EmptyString;
    if (stringValue == "document")
        return FetchRequest::Destination::Document;
    if (stringValue == "sharedworker")
        return FetchRequest::Destination::Sharedworker;
    if (stringValue == "subresource")
        return FetchRequest::Destination::Subresource;
    if (stringValue == "unknown")
        return FetchRequest::Destination::Unknown;
    if (stringValue == "worker")
        return FetchRequest::Destination::Worker;
    return Nullopt;
}

template<> FetchRequest::Destination convert<FetchRequest::Destination>(ExecState& state, JSValue value)
{
    VM& vm = state.vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    auto result = parse<FetchRequest::Destination>(state, value);
    if (UNLIKELY(!result)) {
        throwTypeError(&state, throwScope);
        return { };
    }
    return result.value();
}

template<> inline const char* expectedEnumerationValues<FetchRequest::Destination>()
{
    return "\"\", \"document\", \"sharedworker\", \"subresource\", \"unknown\", \"worker\"";
}

JSString* jsStringWithCache(ExecState*, FetchRequest::Mode);

JSString* jsStringWithCache(ExecState* state, FetchRequest::Mode enumerationValue)
{
    static NeverDestroyed<const String> values[] = {
        ASCIILiteral("navigate"),
        ASCIILiteral("same-origin"),
        ASCIILiteral("no-cors"),
        ASCIILiteral("cors"),
    };
    static_assert(static_cast<size_t>(FetchRequest::Mode::Navigate) == 0, "FetchRequest::Mode::Navigate is not 0 as expected");
    static_assert(static_cast<size_t>(FetchRequest::Mode::SameOrigin) == 1, "FetchRequest::Mode::SameOrigin is not 1 as expected");
    static_assert(static_cast<size_t>(FetchRequest::Mode::NoCors) == 2, "FetchRequest::Mode::NoCors is not 2 as expected");
    static_assert(static_cast<size_t>(FetchRequest::Mode::Cors) == 3, "FetchRequest::Mode::Cors is not 3 as expected");
    ASSERT(static_cast<size_t>(enumerationValue) < WTF_ARRAY_LENGTH(values));
    return jsStringWithCache(state, values[static_cast<size_t>(enumerationValue)]);
}

template<> struct JSValueTraits<FetchRequest::Mode> {
    static JSString* arrayJSValue(ExecState* state, JSDOMGlobalObject*, FetchRequest::Mode value) { return jsStringWithCache(state, value); }
};

template<> Optional<FetchRequest::Mode> parse<FetchRequest::Mode>(ExecState& state, JSValue value)
{
    auto stringValue = value.toWTFString(&state);
    if (stringValue == "navigate")
        return FetchRequest::Mode::Navigate;
    if (stringValue == "same-origin")
        return FetchRequest::Mode::SameOrigin;
    if (stringValue == "no-cors")
        return FetchRequest::Mode::NoCors;
    if (stringValue == "cors")
        return FetchRequest::Mode::Cors;
    return Nullopt;
}

template<> FetchRequest::Mode convert<FetchRequest::Mode>(ExecState& state, JSValue value)
{
    VM& vm = state.vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    auto result = parse<FetchRequest::Mode>(state, value);
    if (UNLIKELY(!result)) {
        throwTypeError(&state, throwScope);
        return { };
    }
    return result.value();
}

template<> inline const char* expectedEnumerationValues<FetchRequest::Mode>()
{
    return "\"navigate\", \"same-origin\", \"no-cors\", \"cors\"";
}

JSString* jsStringWithCache(ExecState*, FetchRequest::Credentials);

JSString* jsStringWithCache(ExecState* state, FetchRequest::Credentials enumerationValue)
{
    static NeverDestroyed<const String> values[] = {
        ASCIILiteral("omit"),
        ASCIILiteral("same-origin"),
        ASCIILiteral("include"),
    };
    static_assert(static_cast<size_t>(FetchRequest::Credentials::Omit) == 0, "FetchRequest::Credentials::Omit is not 0 as expected");
    static_assert(static_cast<size_t>(FetchRequest::Credentials::SameOrigin) == 1, "FetchRequest::Credentials::SameOrigin is not 1 as expected");
    static_assert(static_cast<size_t>(FetchRequest::Credentials::Include) == 2, "FetchRequest::Credentials::Include is not 2 as expected");
    ASSERT(static_cast<size_t>(enumerationValue) < WTF_ARRAY_LENGTH(values));
    return jsStringWithCache(state, values[static_cast<size_t>(enumerationValue)]);
}

template<> struct JSValueTraits<FetchRequest::Credentials> {
    static JSString* arrayJSValue(ExecState* state, JSDOMGlobalObject*, FetchRequest::Credentials value) { return jsStringWithCache(state, value); }
};

template<> Optional<FetchRequest::Credentials> parse<FetchRequest::Credentials>(ExecState& state, JSValue value)
{
    auto stringValue = value.toWTFString(&state);
    if (stringValue == "omit")
        return FetchRequest::Credentials::Omit;
    if (stringValue == "same-origin")
        return FetchRequest::Credentials::SameOrigin;
    if (stringValue == "include")
        return FetchRequest::Credentials::Include;
    return Nullopt;
}

template<> FetchRequest::Credentials convert<FetchRequest::Credentials>(ExecState& state, JSValue value)
{
    VM& vm = state.vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    auto result = parse<FetchRequest::Credentials>(state, value);
    if (UNLIKELY(!result)) {
        throwTypeError(&state, throwScope);
        return { };
    }
    return result.value();
}

template<> inline const char* expectedEnumerationValues<FetchRequest::Credentials>()
{
    return "\"omit\", \"same-origin\", \"include\"";
}

JSString* jsStringWithCache(ExecState*, FetchRequest::Cache);

JSString* jsStringWithCache(ExecState* state, FetchRequest::Cache enumerationValue)
{
    static NeverDestroyed<const String> values[] = {
        ASCIILiteral("default"),
        ASCIILiteral("no-store"),
        ASCIILiteral("reload"),
        ASCIILiteral("no-cache"),
        ASCIILiteral("force-cache"),
    };
    static_assert(static_cast<size_t>(FetchRequest::Cache::Default) == 0, "FetchRequest::Cache::Default is not 0 as expected");
    static_assert(static_cast<size_t>(FetchRequest::Cache::NoStore) == 1, "FetchRequest::Cache::NoStore is not 1 as expected");
    static_assert(static_cast<size_t>(FetchRequest::Cache::Reload) == 2, "FetchRequest::Cache::Reload is not 2 as expected");
    static_assert(static_cast<size_t>(FetchRequest::Cache::NoCache) == 3, "FetchRequest::Cache::NoCache is not 3 as expected");
    static_assert(static_cast<size_t>(FetchRequest::Cache::ForceCache) == 4, "FetchRequest::Cache::ForceCache is not 4 as expected");
    ASSERT(static_cast<size_t>(enumerationValue) < WTF_ARRAY_LENGTH(values));
    return jsStringWithCache(state, values[static_cast<size_t>(enumerationValue)]);
}

template<> struct JSValueTraits<FetchRequest::Cache> {
    static JSString* arrayJSValue(ExecState* state, JSDOMGlobalObject*, FetchRequest::Cache value) { return jsStringWithCache(state, value); }
};

template<> Optional<FetchRequest::Cache> parse<FetchRequest::Cache>(ExecState& state, JSValue value)
{
    auto stringValue = value.toWTFString(&state);
    if (stringValue == "default")
        return FetchRequest::Cache::Default;
    if (stringValue == "no-store")
        return FetchRequest::Cache::NoStore;
    if (stringValue == "reload")
        return FetchRequest::Cache::Reload;
    if (stringValue == "no-cache")
        return FetchRequest::Cache::NoCache;
    if (stringValue == "force-cache")
        return FetchRequest::Cache::ForceCache;
    return Nullopt;
}

template<> FetchRequest::Cache convert<FetchRequest::Cache>(ExecState& state, JSValue value)
{
    VM& vm = state.vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    auto result = parse<FetchRequest::Cache>(state, value);
    if (UNLIKELY(!result)) {
        throwTypeError(&state, throwScope);
        return { };
    }
    return result.value();
}

template<> inline const char* expectedEnumerationValues<FetchRequest::Cache>()
{
    return "\"default\", \"no-store\", \"reload\", \"no-cache\", \"force-cache\"";
}

JSString* jsStringWithCache(ExecState*, FetchRequest::Redirect);

JSString* jsStringWithCache(ExecState* state, FetchRequest::Redirect enumerationValue)
{
    static NeverDestroyed<const String> values[] = {
        ASCIILiteral("follow"),
        ASCIILiteral("error"),
        ASCIILiteral("manual"),
    };
    static_assert(static_cast<size_t>(FetchRequest::Redirect::Follow) == 0, "FetchRequest::Redirect::Follow is not 0 as expected");
    static_assert(static_cast<size_t>(FetchRequest::Redirect::Error) == 1, "FetchRequest::Redirect::Error is not 1 as expected");
    static_assert(static_cast<size_t>(FetchRequest::Redirect::Manual) == 2, "FetchRequest::Redirect::Manual is not 2 as expected");
    ASSERT(static_cast<size_t>(enumerationValue) < WTF_ARRAY_LENGTH(values));
    return jsStringWithCache(state, values[static_cast<size_t>(enumerationValue)]);
}

template<> struct JSValueTraits<FetchRequest::Redirect> {
    static JSString* arrayJSValue(ExecState* state, JSDOMGlobalObject*, FetchRequest::Redirect value) { return jsStringWithCache(state, value); }
};

template<> Optional<FetchRequest::Redirect> parse<FetchRequest::Redirect>(ExecState& state, JSValue value)
{
    auto stringValue = value.toWTFString(&state);
    if (stringValue == "follow")
        return FetchRequest::Redirect::Follow;
    if (stringValue == "error")
        return FetchRequest::Redirect::Error;
    if (stringValue == "manual")
        return FetchRequest::Redirect::Manual;
    return Nullopt;
}

template<> FetchRequest::Redirect convert<FetchRequest::Redirect>(ExecState& state, JSValue value)
{
    VM& vm = state.vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    auto result = parse<FetchRequest::Redirect>(state, value);
    if (UNLIKELY(!result)) {
        throwTypeError(&state, throwScope);
        return { };
    }
    return result.value();
}

template<> inline const char* expectedEnumerationValues<FetchRequest::Redirect>()
{
    return "\"follow\", \"error\", \"manual\"";
}

JSString* jsStringWithCache(ExecState*, FetchRequest::ReferrerPolicy);

JSString* jsStringWithCache(ExecState* state, FetchRequest::ReferrerPolicy enumerationValue)
{
    static NeverDestroyed<const String> values[] = {
        emptyString(),
        ASCIILiteral("no-referrer"),
        ASCIILiteral("no-referrer-when-downgrade"),
        ASCIILiteral("origin"),
        ASCIILiteral("origin-when-cross-origin"),
        ASCIILiteral("unsafe-url"),
    };
    static_assert(static_cast<size_t>(FetchRequest::ReferrerPolicy::EmptyString) == 0, "FetchRequest::ReferrerPolicy::EmptyString is not 0 as expected");
    static_assert(static_cast<size_t>(FetchRequest::ReferrerPolicy::NoReferrer) == 1, "FetchRequest::ReferrerPolicy::NoReferrer is not 1 as expected");
    static_assert(static_cast<size_t>(FetchRequest::ReferrerPolicy::NoReferrerWhenDowngrade) == 2, "FetchRequest::ReferrerPolicy::NoReferrerWhenDowngrade is not 2 as expected");
    static_assert(static_cast<size_t>(FetchRequest::ReferrerPolicy::Origin) == 3, "FetchRequest::ReferrerPolicy::Origin is not 3 as expected");
    static_assert(static_cast<size_t>(FetchRequest::ReferrerPolicy::OriginWhenCrossOrigin) == 4, "FetchRequest::ReferrerPolicy::OriginWhenCrossOrigin is not 4 as expected");
    static_assert(static_cast<size_t>(FetchRequest::ReferrerPolicy::UnsafeUrl) == 5, "FetchRequest::ReferrerPolicy::UnsafeUrl is not 5 as expected");
    ASSERT(static_cast<size_t>(enumerationValue) < WTF_ARRAY_LENGTH(values));
    return jsStringWithCache(state, values[static_cast<size_t>(enumerationValue)]);
}

template<> struct JSValueTraits<FetchRequest::ReferrerPolicy> {
    static JSString* arrayJSValue(ExecState* state, JSDOMGlobalObject*, FetchRequest::ReferrerPolicy value) { return jsStringWithCache(state, value); }
};

template<> Optional<FetchRequest::ReferrerPolicy> parse<FetchRequest::ReferrerPolicy>(ExecState& state, JSValue value)
{
    auto stringValue = value.toWTFString(&state);
    if (stringValue.isEmpty())
        return FetchRequest::ReferrerPolicy::EmptyString;
    if (stringValue == "no-referrer")
        return FetchRequest::ReferrerPolicy::NoReferrer;
    if (stringValue == "no-referrer-when-downgrade")
        return FetchRequest::ReferrerPolicy::NoReferrerWhenDowngrade;
    if (stringValue == "origin")
        return FetchRequest::ReferrerPolicy::Origin;
    if (stringValue == "origin-when-cross-origin")
        return FetchRequest::ReferrerPolicy::OriginWhenCrossOrigin;
    if (stringValue == "unsafe-url")
        return FetchRequest::ReferrerPolicy::UnsafeUrl;
    return Nullopt;
}

template<> FetchRequest::ReferrerPolicy convert<FetchRequest::ReferrerPolicy>(ExecState& state, JSValue value)
{
    VM& vm = state.vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    auto result = parse<FetchRequest::ReferrerPolicy>(state, value);
    if (UNLIKELY(!result)) {
        throwTypeError(&state, throwScope);
        return { };
    }
    return result.value();
}

template<> inline const char* expectedEnumerationValues<FetchRequest::ReferrerPolicy>()
{
    return "\"\", \"no-referrer\", \"no-referrer-when-downgrade\", \"origin\", \"origin-when-cross-origin\", \"unsafe-url\"";
}

// Functions

JSC::EncodedJSValue JSC_HOST_CALL jsFetchRequestPrototypeFunctionClone(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsFetchRequestPrototypeFunctionInitializeWith(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsFetchRequestPrototypeFunctionSetBody(JSC::ExecState*);
#if ENABLE(FETCH_API)
JSC::EncodedJSValue JSC_HOST_CALL jsFetchRequestPrototypeFunctionArrayBuffer(JSC::ExecState*);
#endif
#if ENABLE(FETCH_API)
JSC::EncodedJSValue JSC_HOST_CALL jsFetchRequestPrototypeFunctionBlob(JSC::ExecState*);
#endif
#if ENABLE(FETCH_API)
JSC::EncodedJSValue JSC_HOST_CALL jsFetchRequestPrototypeFunctionFormData(JSC::ExecState*);
#endif
#if ENABLE(FETCH_API)
JSC::EncodedJSValue JSC_HOST_CALL jsFetchRequestPrototypeFunctionJson(JSC::ExecState*);
#endif
#if ENABLE(FETCH_API)
JSC::EncodedJSValue JSC_HOST_CALL jsFetchRequestPrototypeFunctionText(JSC::ExecState*);
#endif

// Attributes

JSC::EncodedJSValue jsFetchRequestMethod(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsFetchRequestUrl(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsFetchRequestHeaders(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsFetchRequestType(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsFetchRequestDestination(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsFetchRequestReferrer(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsFetchRequestReferrerPolicy(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsFetchRequestMode(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsFetchRequestCredentials(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsFetchRequestCache(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsFetchRequestRedirect(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsFetchRequestIntegrity(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
#if ENABLE(FETCH_API)
JSC::EncodedJSValue jsFetchRequestBodyUsed(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
#endif
JSC::EncodedJSValue jsFetchRequestConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSFetchRequestConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);

class JSFetchRequestPrototype : public JSC::JSNonFinalObject {
public:
    typedef JSC::JSNonFinalObject Base;
    static JSFetchRequestPrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
    {
        JSFetchRequestPrototype* ptr = new (NotNull, JSC::allocateCell<JSFetchRequestPrototype>(vm.heap)) JSFetchRequestPrototype(vm, globalObject, structure);
        ptr->finishCreation(vm);
        return ptr;
    }

    DECLARE_INFO;
    static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
    {
        return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
    }

private:
    JSFetchRequestPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
        : JSC::JSNonFinalObject(vm, structure)
    {
    }

    void finishCreation(JSC::VM&);
};

typedef JSBuiltinConstructor<JSFetchRequest> JSFetchRequestConstructor;

template<> JSValue JSFetchRequestConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
{
    UNUSED_PARAM(vm);
    return globalObject.functionPrototype();
}

template<> void JSFetchRequestConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
{
    putDirect(vm, vm.propertyNames->prototype, JSFetchRequest::prototype(vm, &globalObject), DontDelete | ReadOnly | DontEnum);
    putDirect(vm, vm.propertyNames->name, jsNontrivialString(&vm, String(ASCIILiteral("Request"))), ReadOnly | DontEnum);
    putDirect(vm, vm.propertyNames->length, jsNumber(1), ReadOnly | DontEnum);
}

template<> FunctionExecutable* JSFetchRequestConstructor::initializeExecutable(VM& vm)
{
    return fetchRequestInitializeFetchRequestCodeGenerator(vm);
}

template<> const ClassInfo JSFetchRequestConstructor::s_info = { "Request", &Base::s_info, 0, CREATE_METHOD_TABLE(JSFetchRequestConstructor) };

/* Hash table for prototype */

static const HashTableValue JSFetchRequestPrototypeTableValues[] =
{
    { "constructor", DontEnum, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsFetchRequestConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSFetchRequestConstructor) } },
    { "method", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsFetchRequestMethod), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "url", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsFetchRequestUrl), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "headers", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsFetchRequestHeaders), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "type", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsFetchRequestType), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "destination", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsFetchRequestDestination), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "referrer", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsFetchRequestReferrer), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "referrerPolicy", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsFetchRequestReferrerPolicy), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "mode", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsFetchRequestMode), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "credentials", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsFetchRequestCredentials), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "cache", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsFetchRequestCache), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "redirect", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsFetchRequestRedirect), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "integrity", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsFetchRequestIntegrity), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
#if ENABLE(FETCH_API)
    { "bodyUsed", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsFetchRequestBodyUsed), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
#else
    { 0, 0, NoIntrinsic, { 0, 0 } },
#endif
    { "clone", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsFetchRequestPrototypeFunctionClone), (intptr_t) (0) } },
#if ENABLE(FETCH_API)
    { "arrayBuffer", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsFetchRequestPrototypeFunctionArrayBuffer), (intptr_t) (0) } },
#else
    { 0, 0, NoIntrinsic, { 0, 0 } },
#endif
#if ENABLE(FETCH_API)
    { "blob", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsFetchRequestPrototypeFunctionBlob), (intptr_t) (0) } },
#else
    { 0, 0, NoIntrinsic, { 0, 0 } },
#endif
#if ENABLE(FETCH_API)
    { "formData", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsFetchRequestPrototypeFunctionFormData), (intptr_t) (0) } },
#else
    { 0, 0, NoIntrinsic, { 0, 0 } },
#endif
#if ENABLE(FETCH_API)
    { "json", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsFetchRequestPrototypeFunctionJson), (intptr_t) (0) } },
#else
    { 0, 0, NoIntrinsic, { 0, 0 } },
#endif
#if ENABLE(FETCH_API)
    { "text", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsFetchRequestPrototypeFunctionText), (intptr_t) (0) } },
#else
    { 0, 0, NoIntrinsic, { 0, 0 } },
#endif
};

const ClassInfo JSFetchRequestPrototype::s_info = { "RequestPrototype", &Base::s_info, 0, CREATE_METHOD_TABLE(JSFetchRequestPrototype) };

void JSFetchRequestPrototype::finishCreation(VM& vm)
{
    Base::finishCreation(vm);
    reifyStaticProperties(vm, JSFetchRequestPrototypeTableValues, *this);
#if ENABLE(FETCH_API)
    if (!RuntimeEnabledFeatures::sharedFeatures().fetchAPIEnabled()) {
        Identifier propertyName = Identifier::fromString(&vm, reinterpret_cast<const LChar*>("arrayBuffer"), strlen("arrayBuffer"));
        VM::DeletePropertyModeScope scope(vm, VM::DeletePropertyMode::IgnoreConfigurable);
        JSObject::deleteProperty(this, globalObject()->globalExec(), propertyName);
    }
#endif
#if ENABLE(FETCH_API)
    if (!RuntimeEnabledFeatures::sharedFeatures().fetchAPIEnabled()) {
        Identifier propertyName = Identifier::fromString(&vm, reinterpret_cast<const LChar*>("blob"), strlen("blob"));
        VM::DeletePropertyModeScope scope(vm, VM::DeletePropertyMode::IgnoreConfigurable);
        JSObject::deleteProperty(this, globalObject()->globalExec(), propertyName);
    }
#endif
#if ENABLE(FETCH_API)
    if (!RuntimeEnabledFeatures::sharedFeatures().fetchAPIEnabled()) {
        Identifier propertyName = Identifier::fromString(&vm, reinterpret_cast<const LChar*>("formData"), strlen("formData"));
        VM::DeletePropertyModeScope scope(vm, VM::DeletePropertyMode::IgnoreConfigurable);
        JSObject::deleteProperty(this, globalObject()->globalExec(), propertyName);
    }
#endif
#if ENABLE(FETCH_API)
    if (!RuntimeEnabledFeatures::sharedFeatures().fetchAPIEnabled()) {
        Identifier propertyName = Identifier::fromString(&vm, reinterpret_cast<const LChar*>("json"), strlen("json"));
        VM::DeletePropertyModeScope scope(vm, VM::DeletePropertyMode::IgnoreConfigurable);
        JSObject::deleteProperty(this, globalObject()->globalExec(), propertyName);
    }
#endif
#if ENABLE(FETCH_API)
    if (!RuntimeEnabledFeatures::sharedFeatures().fetchAPIEnabled()) {
        Identifier propertyName = Identifier::fromString(&vm, reinterpret_cast<const LChar*>("text"), strlen("text"));
        VM::DeletePropertyModeScope scope(vm, VM::DeletePropertyMode::IgnoreConfigurable);
        JSObject::deleteProperty(this, globalObject()->globalExec(), propertyName);
    }
#endif
#if ENABLE(FETCH_API)
    if (!RuntimeEnabledFeatures::sharedFeatures().fetchAPIEnabled()) {
        Identifier propertyName = Identifier::fromString(&vm, reinterpret_cast<const LChar*>("bodyUsed"), strlen("bodyUsed"));
        VM::DeletePropertyModeScope scope(vm, VM::DeletePropertyMode::IgnoreConfigurable);
        JSObject::deleteProperty(this, globalObject()->globalExec(), propertyName);
    }
#endif
    JSVMClientData& clientData = *static_cast<JSVMClientData*>(vm.clientData);
    putDirect(vm, clientData.builtinNames().initializeWithPrivateName(), JSFunction::create(vm, globalObject(), 0, String(), jsFetchRequestPrototypeFunctionInitializeWith), ReadOnly | DontEnum);
    putDirect(vm, clientData.builtinNames().initializeWithPrivateName(), JSFunction::create(vm, globalObject(), 0, String(), jsFetchRequestPrototypeFunctionInitializeWith), ReadOnly | DontEnum);
    putDirect(vm, clientData.builtinNames().setBodyPrivateName(), JSFunction::create(vm, globalObject(), 0, String(), jsFetchRequestPrototypeFunctionSetBody), ReadOnly | DontEnum);
}

const ClassInfo JSFetchRequest::s_info = { "Request", &Base::s_info, 0, CREATE_METHOD_TABLE(JSFetchRequest) };

JSFetchRequest::JSFetchRequest(Structure* structure, JSDOMGlobalObject& globalObject, Ref<FetchRequest>&& impl)
    : JSDOMWrapper<FetchRequest>(structure, globalObject, WTFMove(impl))
{
}

JSObject* JSFetchRequest::createPrototype(VM& vm, JSGlobalObject* globalObject)
{
    return JSFetchRequestPrototype::create(vm, globalObject, JSFetchRequestPrototype::createStructure(vm, globalObject, globalObject->objectPrototype()));
}

JSObject* JSFetchRequest::prototype(VM& vm, JSGlobalObject* globalObject)
{
    return getDOMPrototype<JSFetchRequest>(vm, globalObject);
}

void JSFetchRequest::destroy(JSC::JSCell* cell)
{
    JSFetchRequest* thisObject = static_cast<JSFetchRequest*>(cell);
    thisObject->JSFetchRequest::~JSFetchRequest();
}

EncodedJSValue jsFetchRequestMethod(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSFetchRequest*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Request", "method");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.method());
    return JSValue::encode(result);
}


EncodedJSValue jsFetchRequestUrl(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSFetchRequest*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Request", "url");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.url());
    return JSValue::encode(result);
}


EncodedJSValue jsFetchRequestHeaders(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSFetchRequest*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Request", "headers");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = toJS(state, castedThis->globalObject(), impl.headers());
    return JSValue::encode(result);
}


EncodedJSValue jsFetchRequestType(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSFetchRequest*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Request", "type");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.type());
    return JSValue::encode(result);
}


EncodedJSValue jsFetchRequestDestination(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSFetchRequest*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Request", "destination");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.destination());
    return JSValue::encode(result);
}


EncodedJSValue jsFetchRequestReferrer(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSFetchRequest*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Request", "referrer");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.referrer());
    return JSValue::encode(result);
}


EncodedJSValue jsFetchRequestReferrerPolicy(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSFetchRequest*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Request", "referrerPolicy");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.referrerPolicy());
    return JSValue::encode(result);
}


EncodedJSValue jsFetchRequestMode(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSFetchRequest*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Request", "mode");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.mode());
    return JSValue::encode(result);
}


EncodedJSValue jsFetchRequestCredentials(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSFetchRequest*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Request", "credentials");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.credentials());
    return JSValue::encode(result);
}


EncodedJSValue jsFetchRequestCache(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSFetchRequest*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Request", "cache");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.cache());
    return JSValue::encode(result);
}


EncodedJSValue jsFetchRequestRedirect(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSFetchRequest*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Request", "redirect");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.redirect());
    return JSValue::encode(result);
}


EncodedJSValue jsFetchRequestIntegrity(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSFetchRequest*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Request", "integrity");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.integrity());
    return JSValue::encode(result);
}


#if ENABLE(FETCH_API)
EncodedJSValue jsFetchRequestBodyUsed(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSFetchRequest*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Request", "bodyUsed");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsBoolean(impl.isDisturbed());
    return JSValue::encode(result);
}

#endif

EncodedJSValue jsFetchRequestConstructor(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    JSFetchRequestPrototype* domObject = jsDynamicCast<JSFetchRequestPrototype*>(JSValue::decode(thisValue));
    if (UNLIKELY(!domObject))
        return throwVMTypeError(state, throwScope);
    return JSValue::encode(JSFetchRequest::getConstructor(state->vm(), domObject->globalObject()));
}

bool setJSFetchRequestConstructor(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    JSValue value = JSValue::decode(encodedValue);
    JSFetchRequestPrototype* domObject = jsDynamicCast<JSFetchRequestPrototype*>(JSValue::decode(thisValue));
    if (UNLIKELY(!domObject)) {
        throwVMTypeError(state, throwScope);
        return false;
    }
    // Shadowing a built-in constructor
    return domObject->putDirect(state->vm(), state->propertyNames().constructor, value);
}

JSValue JSFetchRequest::getConstructor(VM& vm, const JSGlobalObject* globalObject)
{
    return getDOMConstructor<JSFetchRequestConstructor>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
}

EncodedJSValue JSC_HOST_CALL jsFetchRequestPrototypeFunctionClone(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSFetchRequest*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "Request", "clone");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSFetchRequest::info());
    auto& impl = castedThis->wrapped();
    ExceptionCode ec = 0;
    auto* context = jsCast<JSDOMGlobalObject*>(state->lexicalGlobalObject())->scriptExecutionContext();
    if (!context)
        return JSValue::encode(jsUndefined());
    JSValue result = toJSNewlyCreated(state, castedThis->globalObject(), impl.clone(*context, ec));

    setDOMException(state, throwScope, ec);
    return JSValue::encode(result);
}

static inline EncodedJSValue jsFetchRequestPrototypeFunctionInitializeWith1(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSFetchRequest*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "Request", "initializeWith");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSFetchRequest::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 2))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto input = JSFetchRequest::toWrapped(state->uncheckedArgument(0));
    if (UNLIKELY(!input))
        return throwArgumentTypeError(*state, throwScope, 0, "input", "Request", "initializeWith", "FetchRequest");
    auto init = Dictionary(state, state->uncheckedArgument(1));
    JSValue result = toJS(state, castedThis->globalObject(), impl.initializeWith(*input, WTFMove(init), ec));

    setDOMException(state, throwScope, ec);
    return JSValue::encode(result);
}

static inline EncodedJSValue jsFetchRequestPrototypeFunctionInitializeWith2(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSFetchRequest*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "Request", "initializeWith");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSFetchRequest::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 2))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto input = state->uncheckedArgument(0).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    auto init = Dictionary(state, state->uncheckedArgument(1));
    JSValue result = toJS(state, castedThis->globalObject(), impl.initializeWith(WTFMove(input), WTFMove(init), ec));

    setDOMException(state, throwScope, ec);
    return JSValue::encode(result);
}

EncodedJSValue JSC_HOST_CALL jsFetchRequestPrototypeFunctionInitializeWith(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    size_t argsCount = std::min<size_t>(2, state->argumentCount());
    if (argsCount == 2) {
        JSValue distinguishingArg = state->uncheckedArgument(0);
        if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits(JSFetchRequest::info()))
            return jsFetchRequestPrototypeFunctionInitializeWith1(state);
        return jsFetchRequestPrototypeFunctionInitializeWith2(state);
    }
    return argsCount < 2 ? throwVMError(state, throwScope, createNotEnoughArgumentsError(state)) : throwVMTypeError(state, throwScope);
}

EncodedJSValue JSC_HOST_CALL jsFetchRequestPrototypeFunctionSetBody(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSFetchRequest*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "Request", "setBody");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSFetchRequest::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 2))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto body = state->uncheckedArgument(0);
    FetchRequest* request = nullptr;
    if (!state->uncheckedArgument(1).isUndefinedOrNull()) {
        request = JSFetchRequest::toWrapped(state->uncheckedArgument(1));
        if (UNLIKELY(!request))
            return throwArgumentTypeError(*state, throwScope, 1, "request", "Request", "setBody", "FetchRequest");
    }
    impl.setBody(*state, WTFMove(body), WTFMove(request), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

#if ENABLE(FETCH_API)
static EncodedJSValue jsFetchRequestPrototypeFunctionArrayBufferPromise(ExecState*, Ref<DeferredPromise>&&);

EncodedJSValue JSC_HOST_CALL jsFetchRequestPrototypeFunctionArrayBuffer(ExecState* state)
{
    ASSERT(state);
    return JSValue::encode(callPromiseFunction<jsFetchRequestPrototypeFunctionArrayBufferPromise, PromiseExecutionScope::WindowOrWorker>(*state));
}

static inline EncodedJSValue jsFetchRequestPrototypeFunctionArrayBufferPromise(ExecState* state, Ref<DeferredPromise>&& promise)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSFetchRequest*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "Request", "arrayBuffer");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSFetchRequest::info());
    auto& impl = castedThis->wrapped();
    impl.arrayBuffer(WTFMove(promise));
    return JSValue::encode(jsUndefined());
}

#endif

#if ENABLE(FETCH_API)
static EncodedJSValue jsFetchRequestPrototypeFunctionBlobPromise(ExecState*, Ref<DeferredPromise>&&);

EncodedJSValue JSC_HOST_CALL jsFetchRequestPrototypeFunctionBlob(ExecState* state)
{
    ASSERT(state);
    return JSValue::encode(callPromiseFunction<jsFetchRequestPrototypeFunctionBlobPromise, PromiseExecutionScope::WindowOrWorker>(*state));
}

static inline EncodedJSValue jsFetchRequestPrototypeFunctionBlobPromise(ExecState* state, Ref<DeferredPromise>&& promise)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSFetchRequest*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "Request", "blob");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSFetchRequest::info());
    auto& impl = castedThis->wrapped();
    impl.blob(WTFMove(promise));
    return JSValue::encode(jsUndefined());
}

#endif

#if ENABLE(FETCH_API)
static EncodedJSValue jsFetchRequestPrototypeFunctionFormDataPromise(ExecState*, Ref<DeferredPromise>&&);

EncodedJSValue JSC_HOST_CALL jsFetchRequestPrototypeFunctionFormData(ExecState* state)
{
    ASSERT(state);
    return JSValue::encode(callPromiseFunction<jsFetchRequestPrototypeFunctionFormDataPromise, PromiseExecutionScope::WindowOrWorker>(*state));
}

static inline EncodedJSValue jsFetchRequestPrototypeFunctionFormDataPromise(ExecState* state, Ref<DeferredPromise>&& promise)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSFetchRequest*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "Request", "formData");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSFetchRequest::info());
    auto& impl = castedThis->wrapped();
    impl.formData(WTFMove(promise));
    return JSValue::encode(jsUndefined());
}

#endif

#if ENABLE(FETCH_API)
static EncodedJSValue jsFetchRequestPrototypeFunctionJsonPromise(ExecState*, Ref<DeferredPromise>&&);

EncodedJSValue JSC_HOST_CALL jsFetchRequestPrototypeFunctionJson(ExecState* state)
{
    ASSERT(state);
    return JSValue::encode(callPromiseFunction<jsFetchRequestPrototypeFunctionJsonPromise, PromiseExecutionScope::WindowOrWorker>(*state));
}

static inline EncodedJSValue jsFetchRequestPrototypeFunctionJsonPromise(ExecState* state, Ref<DeferredPromise>&& promise)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSFetchRequest*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "Request", "json");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSFetchRequest::info());
    auto& impl = castedThis->wrapped();
    impl.json(WTFMove(promise));
    return JSValue::encode(jsUndefined());
}

#endif

#if ENABLE(FETCH_API)
static EncodedJSValue jsFetchRequestPrototypeFunctionTextPromise(ExecState*, Ref<DeferredPromise>&&);

EncodedJSValue JSC_HOST_CALL jsFetchRequestPrototypeFunctionText(ExecState* state)
{
    ASSERT(state);
    return JSValue::encode(callPromiseFunction<jsFetchRequestPrototypeFunctionTextPromise, PromiseExecutionScope::WindowOrWorker>(*state));
}

static inline EncodedJSValue jsFetchRequestPrototypeFunctionTextPromise(ExecState* state, Ref<DeferredPromise>&& promise)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSFetchRequest*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "Request", "text");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSFetchRequest::info());
    auto& impl = castedThis->wrapped();
    impl.text(WTFMove(promise));
    return JSValue::encode(jsUndefined());
}

#endif

void JSFetchRequest::visitChildren(JSCell* cell, SlotVisitor& visitor)
{
    auto* thisObject = jsCast<JSFetchRequest*>(cell);
    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
    Base::visitChildren(thisObject, visitor);
}

bool JSFetchRequestOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
{
    auto* jsFetchRequest = jsCast<JSFetchRequest*>(handle.slot()->asCell());
    if (jsFetchRequest->wrapped().hasPendingActivity())
        return true;
    UNUSED_PARAM(visitor);
    return false;
}

void JSFetchRequestOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context)
{
    auto* jsFetchRequest = jsCast<JSFetchRequest*>(handle.slot()->asCell());
    auto& world = *static_cast<DOMWrapperWorld*>(context);
    uncacheWrapper(world, &jsFetchRequest->wrapped(), jsFetchRequest);
}

#if ENABLE(BINDING_INTEGRITY)
#if PLATFORM(WIN)
#pragma warning(disable: 4483)
extern "C" { extern void (*const __identifier("??_7FetchRequest@WebCore@@6B@")[])(); }
#else
extern "C" { extern void* _ZTVN7WebCore12FetchRequestE[]; }
#endif
#endif

JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject* globalObject, Ref<FetchRequest>&& impl)
{

#if ENABLE(BINDING_INTEGRITY)
    void* actualVTablePointer = *(reinterpret_cast<void**>(impl.ptr()));
#if PLATFORM(WIN)
    void* expectedVTablePointer = reinterpret_cast<void*>(__identifier("??_7FetchRequest@WebCore@@6B@"));
#else
    void* expectedVTablePointer = &_ZTVN7WebCore12FetchRequestE[2];
#if COMPILER(CLANG)
    // If this fails FetchRequest does not have a vtable, so you need to add the
    // ImplementationLacksVTable attribute to the interface definition
    static_assert(__is_polymorphic(FetchRequest), "FetchRequest is not polymorphic");
#endif
#endif
    // If you hit this assertion you either have a use after free bug, or
    // FetchRequest has subclasses. If FetchRequest has subclasses that get passed
    // to toJS() we currently require FetchRequest you to opt out of binding hardening
    // by adding the SkipVTableValidation attribute to the interface IDL definition
    RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer);
#endif
    return createWrapper<FetchRequest>(globalObject, WTFMove(impl));
}

JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, FetchRequest& impl)
{
    return wrap(state, globalObject, impl);
}

FetchRequest* JSFetchRequest::toWrapped(JSC::JSValue value)
{
    if (auto* wrapper = jsDynamicCast<JSFetchRequest*>(value))
        return &wrapper->wrapped();
    return nullptr;
}

}

#endif // ENABLE(FETCH_API)
