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

#include "ExceptionCode.h"
#include "HTMLElement.h"
#include "HTMLNames.h"
#include "JSDOMBinding.h"
#include "JSDOMConstructor.h"
#include "JSDOMConvert.h"
#include "JSHTMLCollection.h"
#include "JSHTMLElement.h"
#include "URL.h"
#include <runtime/Error.h>
#include <runtime/JSString.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

// Functions

JSC::EncodedJSValue JSC_HOST_CALL jsHTMLTableRowElementPrototypeFunctionInsertCell(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsHTMLTableRowElementPrototypeFunctionDeleteCell(JSC::ExecState*);

// Attributes

JSC::EncodedJSValue jsHTMLTableRowElementRowIndex(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsHTMLTableRowElementSectionRowIndex(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsHTMLTableRowElementCells(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsHTMLTableRowElementAlign(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSHTMLTableRowElementAlign(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsHTMLTableRowElementBgColor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSHTMLTableRowElementBgColor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsHTMLTableRowElementCh(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSHTMLTableRowElementCh(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsHTMLTableRowElementChOff(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSHTMLTableRowElementChOff(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsHTMLTableRowElementVAlign(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSHTMLTableRowElementVAlign(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsHTMLTableRowElementConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSHTMLTableRowElementConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);

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

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

typedef JSDOMConstructorNotConstructable<JSHTMLTableRowElement> JSHTMLTableRowElementConstructor;

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

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

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

/* Hash table for prototype */

static const HashTableValue JSHTMLTableRowElementPrototypeTableValues[] =
{
    { "constructor", DontEnum, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLTableRowElementConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSHTMLTableRowElementConstructor) } },
    { "rowIndex", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLTableRowElementRowIndex), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "sectionRowIndex", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLTableRowElementSectionRowIndex), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "cells", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLTableRowElementCells), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "align", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLTableRowElementAlign), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSHTMLTableRowElementAlign) } },
    { "bgColor", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLTableRowElementBgColor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSHTMLTableRowElementBgColor) } },
    { "ch", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLTableRowElementCh), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSHTMLTableRowElementCh) } },
    { "chOff", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLTableRowElementChOff), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSHTMLTableRowElementChOff) } },
    { "vAlign", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLTableRowElementVAlign), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSHTMLTableRowElementVAlign) } },
    { "insertCell", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsHTMLTableRowElementPrototypeFunctionInsertCell), (intptr_t) (0) } },
    { "deleteCell", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsHTMLTableRowElementPrototypeFunctionDeleteCell), (intptr_t) (1) } },
};

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

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

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

JSHTMLTableRowElement::JSHTMLTableRowElement(Structure* structure, JSDOMGlobalObject& globalObject, Ref<HTMLTableRowElement>&& impl)
    : JSHTMLElement(structure, globalObject, WTFMove(impl))
{
}

JSObject* JSHTMLTableRowElement::createPrototype(VM& vm, JSGlobalObject* globalObject)
{
    return JSHTMLTableRowElementPrototype::create(vm, globalObject, JSHTMLTableRowElementPrototype::createStructure(vm, globalObject, JSHTMLElement::prototype(vm, globalObject)));
}

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

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


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


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


EncodedJSValue jsHTMLTableRowElementAlign(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<JSHTMLTableRowElement*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "HTMLTableRowElement", "align");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.attributeWithoutSynchronization(WebCore::HTMLNames::alignAttr));
    return JSValue::encode(result);
}


EncodedJSValue jsHTMLTableRowElementBgColor(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<JSHTMLTableRowElement*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "HTMLTableRowElement", "bgColor");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.attributeWithoutSynchronization(WebCore::HTMLNames::bgcolorAttr));
    return JSValue::encode(result);
}


EncodedJSValue jsHTMLTableRowElementCh(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<JSHTMLTableRowElement*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "HTMLTableRowElement", "ch");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.attributeWithoutSynchronization(WebCore::HTMLNames::charAttr));
    return JSValue::encode(result);
}


EncodedJSValue jsHTMLTableRowElementChOff(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<JSHTMLTableRowElement*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "HTMLTableRowElement", "chOff");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.attributeWithoutSynchronization(WebCore::HTMLNames::charoffAttr));
    return JSValue::encode(result);
}


EncodedJSValue jsHTMLTableRowElementVAlign(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<JSHTMLTableRowElement*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "HTMLTableRowElement", "vAlign");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.attributeWithoutSynchronization(WebCore::HTMLNames::valignAttr));
    return JSValue::encode(result);
}


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

bool setJSHTMLTableRowElementConstructor(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    JSValue value = JSValue::decode(encodedValue);
    JSHTMLTableRowElementPrototype* domObject = jsDynamicCast<JSHTMLTableRowElementPrototype*>(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 setJSHTMLTableRowElementAlign(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);
    JSHTMLTableRowElement* castedThis = jsDynamicCast<JSHTMLTableRowElement*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "HTMLTableRowElement", "align");
    }
    auto& impl = castedThis->wrapped();
    auto nativeValue = value.toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, false);
    impl.setAttributeWithoutSynchronization(WebCore::HTMLNames::alignAttr, WTFMove(nativeValue));
    return true;
}


bool setJSHTMLTableRowElementBgColor(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);
    JSHTMLTableRowElement* castedThis = jsDynamicCast<JSHTMLTableRowElement*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "HTMLTableRowElement", "bgColor");
    }
    auto& impl = castedThis->wrapped();
    auto nativeValue = valueToStringTreatingNullAsEmptyString(state, value);
    RETURN_IF_EXCEPTION(throwScope, false);
    impl.setAttributeWithoutSynchronization(WebCore::HTMLNames::bgcolorAttr, WTFMove(nativeValue));
    return true;
}


bool setJSHTMLTableRowElementCh(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);
    JSHTMLTableRowElement* castedThis = jsDynamicCast<JSHTMLTableRowElement*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "HTMLTableRowElement", "ch");
    }
    auto& impl = castedThis->wrapped();
    auto nativeValue = value.toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, false);
    impl.setAttributeWithoutSynchronization(WebCore::HTMLNames::charAttr, WTFMove(nativeValue));
    return true;
}


bool setJSHTMLTableRowElementChOff(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);
    JSHTMLTableRowElement* castedThis = jsDynamicCast<JSHTMLTableRowElement*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "HTMLTableRowElement", "chOff");
    }
    auto& impl = castedThis->wrapped();
    auto nativeValue = value.toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, false);
    impl.setAttributeWithoutSynchronization(WebCore::HTMLNames::charoffAttr, WTFMove(nativeValue));
    return true;
}


bool setJSHTMLTableRowElementVAlign(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);
    JSHTMLTableRowElement* castedThis = jsDynamicCast<JSHTMLTableRowElement*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "HTMLTableRowElement", "vAlign");
    }
    auto& impl = castedThis->wrapped();
    auto nativeValue = value.toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, false);
    impl.setAttributeWithoutSynchronization(WebCore::HTMLNames::valignAttr, WTFMove(nativeValue));
    return true;
}


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

EncodedJSValue JSC_HOST_CALL jsHTMLTableRowElementPrototypeFunctionInsertCell(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSHTMLTableRowElement*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "HTMLTableRowElement", "insertCell");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSHTMLTableRowElement::info());
    auto& impl = castedThis->wrapped();
    ExceptionCode ec = 0;
    auto index = state->argument(0).isUndefined() ? -1 : convert<int32_t>(*state, state->uncheckedArgument(0), NormalConversion);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    JSValue result = toJS(state, castedThis->globalObject(), impl.insertCell(WTFMove(index), ec));

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

EncodedJSValue JSC_HOST_CALL jsHTMLTableRowElementPrototypeFunctionDeleteCell(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSHTMLTableRowElement*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "HTMLTableRowElement", "deleteCell");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSHTMLTableRowElement::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto index = convert<int32_t>(*state, state->uncheckedArgument(0), NormalConversion);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.deleteCell(WTFMove(index), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

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


}
