/*
    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 "JSFileReader.h"

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

using namespace JSC;

namespace WebCore {

// Functions

JSC::EncodedJSValue JSC_HOST_CALL jsFileReaderPrototypeFunctionReadAsArrayBuffer(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsFileReaderPrototypeFunctionReadAsBinaryString(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsFileReaderPrototypeFunctionReadAsText(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsFileReaderPrototypeFunctionReadAsDataURL(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsFileReaderPrototypeFunctionAbort(JSC::ExecState*);

// Attributes

JSC::EncodedJSValue jsFileReaderReadyState(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsFileReaderResult(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsFileReaderError(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsFileReaderOnloadstart(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSFileReaderOnloadstart(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsFileReaderOnprogress(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSFileReaderOnprogress(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsFileReaderOnload(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSFileReaderOnload(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsFileReaderOnabort(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSFileReaderOnabort(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsFileReaderOnerror(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSFileReaderOnerror(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsFileReaderOnloadend(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSFileReaderOnloadend(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsFileReaderConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSFileReaderConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);

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

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

typedef JSDOMConstructor<JSFileReader> JSFileReaderConstructor;

/* Hash table for constructor */

static const HashTableValue JSFileReaderConstructorTableValues[] =
{
    { "EMPTY", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(0) } },
    { "LOADING", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(1) } },
    { "DONE", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(2) } },
};

static_assert(FileReader::EMPTY == 0, "EMPTY in FileReader does not match value from IDL");
static_assert(FileReader::LOADING == 1, "LOADING in FileReader does not match value from IDL");
static_assert(FileReader::DONE == 2, "DONE in FileReader does not match value from IDL");

template<> EncodedJSValue JSC_HOST_CALL JSFileReaderConstructor::construct(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    auto* castedThis = jsCast<JSFileReaderConstructor*>(state->callee());
    ASSERT(castedThis);
    ScriptExecutionContext* context = castedThis->scriptExecutionContext();
    if (UNLIKELY(!context))
        return throwConstructorScriptExecutionContextUnavailableError(*state, throwScope, "FileReader");
    auto object = FileReader::create(*context);
    return JSValue::encode(toJSNewlyCreated(state, castedThis->globalObject(), WTFMove(object)));
}

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

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

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

/* Hash table for prototype */

static const HashTableValue JSFileReaderPrototypeTableValues[] =
{
    { "constructor", DontEnum, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsFileReaderConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSFileReaderConstructor) } },
    { "readyState", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsFileReaderReadyState), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "result", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsFileReaderResult), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "error", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsFileReaderError), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "onloadstart", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsFileReaderOnloadstart), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSFileReaderOnloadstart) } },
    { "onprogress", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsFileReaderOnprogress), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSFileReaderOnprogress) } },
    { "onload", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsFileReaderOnload), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSFileReaderOnload) } },
    { "onabort", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsFileReaderOnabort), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSFileReaderOnabort) } },
    { "onerror", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsFileReaderOnerror), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSFileReaderOnerror) } },
    { "onloadend", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsFileReaderOnloadend), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSFileReaderOnloadend) } },
    { "readAsArrayBuffer", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsFileReaderPrototypeFunctionReadAsArrayBuffer), (intptr_t) (1) } },
    { "readAsBinaryString", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsFileReaderPrototypeFunctionReadAsBinaryString), (intptr_t) (1) } },
    { "readAsText", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsFileReaderPrototypeFunctionReadAsText), (intptr_t) (1) } },
    { "readAsDataURL", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsFileReaderPrototypeFunctionReadAsDataURL), (intptr_t) (1) } },
    { "abort", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsFileReaderPrototypeFunctionAbort), (intptr_t) (0) } },
    { "EMPTY", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(0) } },
    { "LOADING", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(1) } },
    { "DONE", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(2) } },
};

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

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

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

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

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

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

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


EncodedJSValue jsFileReaderResult(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<JSFileReader*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "FileReader", "result");
    }
    return JSValue::encode(castedThis->result(*state));
}


EncodedJSValue jsFileReaderError(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<JSFileReader*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "FileReader", "error");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = toJS(state, castedThis->globalObject(), impl.error());
    return JSValue::encode(result);
}


EncodedJSValue jsFileReaderOnloadstart(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<JSFileReader*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "FileReader", "onloadstart");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().loadstartEvent));
}


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


EncodedJSValue jsFileReaderOnload(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<JSFileReader*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "FileReader", "onload");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().loadEvent));
}


EncodedJSValue jsFileReaderOnabort(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<JSFileReader*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "FileReader", "onabort");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().abortEvent));
}


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


EncodedJSValue jsFileReaderOnloadend(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<JSFileReader*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "FileReader", "onloadend");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().loadendEvent));
}


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

bool setJSFileReaderConstructor(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    JSValue value = JSValue::decode(encodedValue);
    JSFileReaderPrototype* domObject = jsDynamicCast<JSFileReaderPrototype*>(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 setJSFileReaderOnloadstart(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);
    JSFileReader* castedThis = jsDynamicCast<JSFileReader*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "FileReader", "onloadstart");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().loadstartEvent, value);
    return true;
}


bool setJSFileReaderOnprogress(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);
    JSFileReader* castedThis = jsDynamicCast<JSFileReader*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "FileReader", "onprogress");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().progressEvent, value);
    return true;
}


bool setJSFileReaderOnload(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);
    JSFileReader* castedThis = jsDynamicCast<JSFileReader*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "FileReader", "onload");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().loadEvent, value);
    return true;
}


bool setJSFileReaderOnabort(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);
    JSFileReader* castedThis = jsDynamicCast<JSFileReader*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "FileReader", "onabort");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().abortEvent, value);
    return true;
}


bool setJSFileReaderOnerror(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);
    JSFileReader* castedThis = jsDynamicCast<JSFileReader*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "FileReader", "onerror");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().errorEvent, value);
    return true;
}


bool setJSFileReaderOnloadend(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);
    JSFileReader* castedThis = jsDynamicCast<JSFileReader*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "FileReader", "onloadend");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().loadendEvent, value);
    return true;
}


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

EncodedJSValue JSC_HOST_CALL jsFileReaderPrototypeFunctionReadAsArrayBuffer(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSFileReader*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "FileReader", "readAsArrayBuffer");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSFileReader::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    Blob* blob = nullptr;
    if (!state->uncheckedArgument(0).isUndefinedOrNull()) {
        blob = JSBlob::toWrapped(state->uncheckedArgument(0));
        if (UNLIKELY(!blob))
            return throwArgumentTypeError(*state, throwScope, 0, "blob", "FileReader", "readAsArrayBuffer", "Blob");
    }
    impl.readAsArrayBuffer(WTFMove(blob), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsFileReaderPrototypeFunctionReadAsBinaryString(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSFileReader*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "FileReader", "readAsBinaryString");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSFileReader::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    Blob* blob = nullptr;
    if (!state->uncheckedArgument(0).isUndefinedOrNull()) {
        blob = JSBlob::toWrapped(state->uncheckedArgument(0));
        if (UNLIKELY(!blob))
            return throwArgumentTypeError(*state, throwScope, 0, "blob", "FileReader", "readAsBinaryString", "Blob");
    }
    impl.readAsBinaryString(WTFMove(blob), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsFileReaderPrototypeFunctionReadAsText(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSFileReader*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "FileReader", "readAsText");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSFileReader::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    Blob* blob = nullptr;
    if (!state->uncheckedArgument(0).isUndefinedOrNull()) {
        blob = JSBlob::toWrapped(state->uncheckedArgument(0));
        if (UNLIKELY(!blob))
            return throwArgumentTypeError(*state, throwScope, 0, "blob", "FileReader", "readAsText", "Blob");
    }
    auto encoding = state->argument(1).isUndefined() ? String() : state->uncheckedArgument(1).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.readAsText(WTFMove(blob), WTFMove(encoding), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsFileReaderPrototypeFunctionReadAsDataURL(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSFileReader*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "FileReader", "readAsDataURL");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSFileReader::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    Blob* blob = nullptr;
    if (!state->uncheckedArgument(0).isUndefinedOrNull()) {
        blob = JSBlob::toWrapped(state->uncheckedArgument(0));
        if (UNLIKELY(!blob))
            return throwArgumentTypeError(*state, throwScope, 0, "blob", "FileReader", "readAsDataURL", "Blob");
    }
    impl.readAsDataURL(WTFMove(blob), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

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

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

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

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

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

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

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

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

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

}
