/*
    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"
#include "JSDOMApplicationCache.h"

#include "EventNames.h"
#include "ExceptionCode.h"
#include "JSDOMBinding.h"
#include "JSDOMConstructor.h"
#include "JSEventListener.h"
#include <runtime/Error.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

// Functions

JSC::EncodedJSValue JSC_HOST_CALL jsDOMApplicationCachePrototypeFunctionUpdate(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsDOMApplicationCachePrototypeFunctionSwapCache(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsDOMApplicationCachePrototypeFunctionAbort(JSC::ExecState*);

// Attributes

JSC::EncodedJSValue jsDOMApplicationCacheStatus(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsDOMApplicationCacheOnchecking(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSDOMApplicationCacheOnchecking(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsDOMApplicationCacheOnerror(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSDOMApplicationCacheOnerror(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsDOMApplicationCacheOnnoupdate(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSDOMApplicationCacheOnnoupdate(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsDOMApplicationCacheOndownloading(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSDOMApplicationCacheOndownloading(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsDOMApplicationCacheOnprogress(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSDOMApplicationCacheOnprogress(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsDOMApplicationCacheOnupdateready(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSDOMApplicationCacheOnupdateready(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsDOMApplicationCacheOncached(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSDOMApplicationCacheOncached(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsDOMApplicationCacheOnobsolete(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSDOMApplicationCacheOnobsolete(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsDOMApplicationCacheConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSDOMApplicationCacheConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);

class JSDOMApplicationCachePrototype : public JSC::JSNonFinalObject {
public:
    typedef JSC::JSNonFinalObject Base;
    static JSDOMApplicationCachePrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
    {
        JSDOMApplicationCachePrototype* ptr = new (NotNull, JSC::allocateCell<JSDOMApplicationCachePrototype>(vm.heap)) JSDOMApplicationCachePrototype(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:
    JSDOMApplicationCachePrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
        : JSC::JSNonFinalObject(vm, structure)
    {
    }

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

typedef JSDOMConstructorNotConstructable<JSDOMApplicationCache> JSDOMApplicationCacheConstructor;

/* Hash table for constructor */

static const HashTableValue JSDOMApplicationCacheConstructorTableValues[] =
{
    { "UNCACHED", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(0) } },
    { "IDLE", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(1) } },
    { "CHECKING", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(2) } },
    { "DOWNLOADING", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(3) } },
    { "UPDATEREADY", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(4) } },
    { "OBSOLETE", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(5) } },
};

template<> JSValue JSDOMApplicationCacheConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
{
    return JSEventTarget::getConstructor(vm, &globalObject);
}

template<> void JSDOMApplicationCacheConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
{
    putDirect(vm, vm.propertyNames->prototype, JSDOMApplicationCache::prototype(vm, &globalObject), DontDelete | ReadOnly | DontEnum);
    putDirect(vm, vm.propertyNames->name, jsNontrivialString(&vm, String(ASCIILiteral("ApplicationCache"))), ReadOnly | DontEnum);
    putDirect(vm, vm.propertyNames->length, jsNumber(0), ReadOnly | DontEnum);
    reifyStaticProperties(vm, JSDOMApplicationCacheConstructorTableValues, *this);
}

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

/* Hash table for prototype */

static const HashTableValue JSDOMApplicationCachePrototypeTableValues[] =
{
    { "constructor", DontEnum, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsDOMApplicationCacheConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSDOMApplicationCacheConstructor) } },
    { "status", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsDOMApplicationCacheStatus), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "onchecking", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsDOMApplicationCacheOnchecking), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSDOMApplicationCacheOnchecking) } },
    { "onerror", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsDOMApplicationCacheOnerror), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSDOMApplicationCacheOnerror) } },
    { "onnoupdate", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsDOMApplicationCacheOnnoupdate), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSDOMApplicationCacheOnnoupdate) } },
    { "ondownloading", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsDOMApplicationCacheOndownloading), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSDOMApplicationCacheOndownloading) } },
    { "onprogress", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsDOMApplicationCacheOnprogress), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSDOMApplicationCacheOnprogress) } },
    { "onupdateready", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsDOMApplicationCacheOnupdateready), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSDOMApplicationCacheOnupdateready) } },
    { "oncached", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsDOMApplicationCacheOncached), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSDOMApplicationCacheOncached) } },
    { "onobsolete", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsDOMApplicationCacheOnobsolete), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSDOMApplicationCacheOnobsolete) } },
    { "update", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsDOMApplicationCachePrototypeFunctionUpdate), (intptr_t) (0) } },
    { "swapCache", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsDOMApplicationCachePrototypeFunctionSwapCache), (intptr_t) (0) } },
    { "abort", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsDOMApplicationCachePrototypeFunctionAbort), (intptr_t) (0) } },
    { "UNCACHED", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(0) } },
    { "IDLE", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(1) } },
    { "CHECKING", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(2) } },
    { "DOWNLOADING", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(3) } },
    { "UPDATEREADY", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(4) } },
    { "OBSOLETE", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(5) } },
};

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

void JSDOMApplicationCachePrototype::finishCreation(VM& vm)
{
    Base::finishCreation(vm);
    reifyStaticProperties(vm, JSDOMApplicationCachePrototypeTableValues, *this);
}

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

JSDOMApplicationCache::JSDOMApplicationCache(Structure* structure, JSDOMGlobalObject& globalObject, Ref<DOMApplicationCache>&& impl)
    : JSEventTarget(structure, globalObject, WTFMove(impl))
{
}

JSObject* JSDOMApplicationCache::createPrototype(VM& vm, JSGlobalObject* globalObject)
{
    return JSDOMApplicationCachePrototype::create(vm, globalObject, JSDOMApplicationCachePrototype::createStructure(vm, globalObject, JSEventTarget::prototype(vm, globalObject)));
}

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

EncodedJSValue jsDOMApplicationCacheStatus(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<JSDOMApplicationCache*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "ApplicationCache", "status");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsNumber(impl.status());
    return JSValue::encode(result);
}


EncodedJSValue jsDOMApplicationCacheOnchecking(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<JSDOMApplicationCache*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "ApplicationCache", "onchecking");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().checkingEvent));
}


EncodedJSValue jsDOMApplicationCacheOnerror(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<JSDOMApplicationCache*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "ApplicationCache", "onerror");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().errorEvent));
}


EncodedJSValue jsDOMApplicationCacheOnnoupdate(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<JSDOMApplicationCache*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "ApplicationCache", "onnoupdate");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().noupdateEvent));
}


EncodedJSValue jsDOMApplicationCacheOndownloading(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<JSDOMApplicationCache*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "ApplicationCache", "ondownloading");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().downloadingEvent));
}


EncodedJSValue jsDOMApplicationCacheOnprogress(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<JSDOMApplicationCache*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "ApplicationCache", "onprogress");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().progressEvent));
}


EncodedJSValue jsDOMApplicationCacheOnupdateready(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<JSDOMApplicationCache*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "ApplicationCache", "onupdateready");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().updatereadyEvent));
}


EncodedJSValue jsDOMApplicationCacheOncached(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<JSDOMApplicationCache*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "ApplicationCache", "oncached");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().cachedEvent));
}


EncodedJSValue jsDOMApplicationCacheOnobsolete(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<JSDOMApplicationCache*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "ApplicationCache", "onobsolete");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().obsoleteEvent));
}


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

bool setJSDOMApplicationCacheConstructor(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    JSValue value = JSValue::decode(encodedValue);
    JSDOMApplicationCachePrototype* domObject = jsDynamicCast<JSDOMApplicationCachePrototype*>(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);
}

bool setJSDOMApplicationCacheOnchecking(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue value = JSValue::decode(encodedValue);
    UNUSED_PARAM(thisValue);
    JSDOMApplicationCache* castedThis = jsDynamicCast<JSDOMApplicationCache*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "ApplicationCache", "onchecking");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().checkingEvent, value);
    return true;
}


bool setJSDOMApplicationCacheOnerror(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue value = JSValue::decode(encodedValue);
    UNUSED_PARAM(thisValue);
    JSDOMApplicationCache* castedThis = jsDynamicCast<JSDOMApplicationCache*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "ApplicationCache", "onerror");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().errorEvent, value);
    return true;
}


bool setJSDOMApplicationCacheOnnoupdate(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue value = JSValue::decode(encodedValue);
    UNUSED_PARAM(thisValue);
    JSDOMApplicationCache* castedThis = jsDynamicCast<JSDOMApplicationCache*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "ApplicationCache", "onnoupdate");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().noupdateEvent, value);
    return true;
}


bool setJSDOMApplicationCacheOndownloading(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue value = JSValue::decode(encodedValue);
    UNUSED_PARAM(thisValue);
    JSDOMApplicationCache* castedThis = jsDynamicCast<JSDOMApplicationCache*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "ApplicationCache", "ondownloading");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().downloadingEvent, value);
    return true;
}


bool setJSDOMApplicationCacheOnprogress(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue value = JSValue::decode(encodedValue);
    UNUSED_PARAM(thisValue);
    JSDOMApplicationCache* castedThis = jsDynamicCast<JSDOMApplicationCache*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "ApplicationCache", "onprogress");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().progressEvent, value);
    return true;
}


bool setJSDOMApplicationCacheOnupdateready(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue value = JSValue::decode(encodedValue);
    UNUSED_PARAM(thisValue);
    JSDOMApplicationCache* castedThis = jsDynamicCast<JSDOMApplicationCache*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "ApplicationCache", "onupdateready");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().updatereadyEvent, value);
    return true;
}


bool setJSDOMApplicationCacheOncached(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue value = JSValue::decode(encodedValue);
    UNUSED_PARAM(thisValue);
    JSDOMApplicationCache* castedThis = jsDynamicCast<JSDOMApplicationCache*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "ApplicationCache", "oncached");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().cachedEvent, value);
    return true;
}


bool setJSDOMApplicationCacheOnobsolete(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue value = JSValue::decode(encodedValue);
    UNUSED_PARAM(thisValue);
    JSDOMApplicationCache* castedThis = jsDynamicCast<JSDOMApplicationCache*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "ApplicationCache", "onobsolete");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().obsoleteEvent, value);
    return true;
}


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

EncodedJSValue JSC_HOST_CALL jsDOMApplicationCachePrototypeFunctionUpdate(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSDOMApplicationCache*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "ApplicationCache", "update");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSDOMApplicationCache::info());
    auto& impl = castedThis->wrapped();
    ExceptionCode ec = 0;
    impl.update(ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsDOMApplicationCachePrototypeFunctionSwapCache(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSDOMApplicationCache*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "ApplicationCache", "swapCache");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSDOMApplicationCache::info());
    auto& impl = castedThis->wrapped();
    ExceptionCode ec = 0;
    impl.swapCache(ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsDOMApplicationCachePrototypeFunctionAbort(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSDOMApplicationCache*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "ApplicationCache", "abort");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSDOMApplicationCache::info());
    auto& impl = castedThis->wrapped();
    impl.abort();
    return JSValue::encode(jsUndefined());
}

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

bool JSDOMApplicationCacheOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
{
    auto* jsDOMApplicationCache = jsCast<JSDOMApplicationCache*>(handle.slot()->asCell());
    if (jsDOMApplicationCache->wrapped().isFiringEventListeners())
        return true;
    Frame* root = WTF::getPtr(jsDOMApplicationCache->wrapped().frame());
    if (!root)
        return false;
    return visitor.containsOpaqueRoot(root);
}

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

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

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

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

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

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

}
