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

#include "HTMLCollection.h"
#include "HTMLElement.h"
#include "HTMLTableCaptionElement.h"
#include "HTMLTableElement.h"
#include "HTMLTableSectionElement.h"
#include "JSHTMLCollection.h"
#include "JSHTMLElement.h"
#include "JSHTMLTableCaptionElement.h"
#include "JSHTMLTableSectionElement.h"
#include "KURL.h"
#include <runtime/Error.h>
#include <runtime/JSString.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

ASSERT_CLASS_FITS_IN_CELL(JSHTMLTableElement);

/* Hash table */

static const HashTableValue JSHTMLTableElementTableValues[16] =
{
    { "caption", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLTableElementCaption), (intptr_t)setJSHTMLTableElementCaption },
    { "tHead", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLTableElementTHead), (intptr_t)setJSHTMLTableElementTHead },
    { "tFoot", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLTableElementTFoot), (intptr_t)setJSHTMLTableElementTFoot },
    { "rows", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLTableElementRows), (intptr_t)0 },
    { "tBodies", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLTableElementTBodies), (intptr_t)0 },
    { "align", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLTableElementAlign), (intptr_t)setJSHTMLTableElementAlign },
    { "bgColor", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLTableElementBgColor), (intptr_t)setJSHTMLTableElementBgColor },
    { "border", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLTableElementBorder), (intptr_t)setJSHTMLTableElementBorder },
    { "cellPadding", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLTableElementCellPadding), (intptr_t)setJSHTMLTableElementCellPadding },
    { "cellSpacing", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLTableElementCellSpacing), (intptr_t)setJSHTMLTableElementCellSpacing },
    { "frame", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLTableElementFrame), (intptr_t)setJSHTMLTableElementFrame },
    { "rules", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLTableElementRules), (intptr_t)setJSHTMLTableElementRules },
    { "summary", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLTableElementSummary), (intptr_t)setJSHTMLTableElementSummary },
    { "width", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLTableElementWidth), (intptr_t)setJSHTMLTableElementWidth },
    { "constructor", DontEnum|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLTableElementConstructor), (intptr_t)0 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSHTMLTableElementTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 127, JSHTMLTableElementTableValues, 0 };
#else
    { 35, 31, JSHTMLTableElementTableValues, 0 };
#endif

/* Hash table for constructor */

static const HashTableValue JSHTMLTableElementConstructorTableValues[1] =
{
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSHTMLTableElementConstructorTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 0, JSHTMLTableElementConstructorTableValues, 0 };
#else
    { 1, 0, JSHTMLTableElementConstructorTableValues, 0 };
#endif

class JSHTMLTableElementConstructor : public DOMConstructorObject {
public:
    JSHTMLTableElementConstructor(ExecState* exec, JSDOMGlobalObject* globalObject)
        : DOMConstructorObject(JSHTMLTableElementConstructor::createStructure(globalObject->objectPrototype()), globalObject)
    {
        putDirect(exec->propertyNames().prototype, JSHTMLTableElementPrototype::self(exec, globalObject), None);
    }
    virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
    virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
    virtual const ClassInfo* classInfo() const { return &s_info; }
    static const ClassInfo s_info;

    static PassRefPtr<Structure> createStructure(JSValue proto) 
    { 
        return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); 
    }
    
protected:
    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | DOMConstructorObject::StructureFlags;
};

const ClassInfo JSHTMLTableElementConstructor::s_info = { "HTMLTableElementConstructor", 0, &JSHTMLTableElementConstructorTable, 0 };

bool JSHTMLTableElementConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticValueSlot<JSHTMLTableElementConstructor, DOMObject>(exec, &JSHTMLTableElementConstructorTable, this, propertyName, slot);
}

bool JSHTMLTableElementConstructor::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticValueDescriptor<JSHTMLTableElementConstructor, DOMObject>(exec, &JSHTMLTableElementConstructorTable, this, propertyName, descriptor);
}

/* Hash table for prototype */

static const HashTableValue JSHTMLTableElementPrototypeTableValues[9] =
{
    { "createTHead", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsHTMLTableElementPrototypeFunctionCreateTHead), (intptr_t)0 },
    { "deleteTHead", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsHTMLTableElementPrototypeFunctionDeleteTHead), (intptr_t)0 },
    { "createTFoot", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsHTMLTableElementPrototypeFunctionCreateTFoot), (intptr_t)0 },
    { "deleteTFoot", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsHTMLTableElementPrototypeFunctionDeleteTFoot), (intptr_t)0 },
    { "createCaption", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsHTMLTableElementPrototypeFunctionCreateCaption), (intptr_t)0 },
    { "deleteCaption", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsHTMLTableElementPrototypeFunctionDeleteCaption), (intptr_t)0 },
    { "insertRow", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsHTMLTableElementPrototypeFunctionInsertRow), (intptr_t)1 },
    { "deleteRow", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsHTMLTableElementPrototypeFunctionDeleteRow), (intptr_t)1 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSHTMLTableElementPrototypeTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 127, JSHTMLTableElementPrototypeTableValues, 0 };
#else
    { 19, 15, JSHTMLTableElementPrototypeTableValues, 0 };
#endif

const ClassInfo JSHTMLTableElementPrototype::s_info = { "HTMLTableElementPrototype", 0, &JSHTMLTableElementPrototypeTable, 0 };

JSObject* JSHTMLTableElementPrototype::self(ExecState* exec, JSGlobalObject* globalObject)
{
    return getDOMPrototype<JSHTMLTableElement>(exec, globalObject);
}

bool JSHTMLTableElementPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticFunctionSlot<JSObject>(exec, &JSHTMLTableElementPrototypeTable, this, propertyName, slot);
}

bool JSHTMLTableElementPrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticFunctionDescriptor<JSObject>(exec, &JSHTMLTableElementPrototypeTable, this, propertyName, descriptor);
}

const ClassInfo JSHTMLTableElement::s_info = { "HTMLTableElement", &JSHTMLElement::s_info, &JSHTMLTableElementTable, 0 };

JSHTMLTableElement::JSHTMLTableElement(NonNullPassRefPtr<Structure> structure, JSDOMGlobalObject* globalObject, PassRefPtr<HTMLTableElement> impl)
    : JSHTMLElement(structure, globalObject, impl)
{
}

JSObject* JSHTMLTableElement::createPrototype(ExecState* exec, JSGlobalObject* globalObject)
{
    return new (exec) JSHTMLTableElementPrototype(JSHTMLTableElementPrototype::createStructure(JSHTMLElementPrototype::self(exec, globalObject)));
}

bool JSHTMLTableElement::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticValueSlot<JSHTMLTableElement, Base>(exec, &JSHTMLTableElementTable, this, propertyName, slot);
}

bool JSHTMLTableElement::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticValueDescriptor<JSHTMLTableElement, Base>(exec, &JSHTMLTableElementTable, this, propertyName, descriptor);
}

JSValue jsHTMLTableElementCaption(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSHTMLTableElement* castedThis = static_cast<JSHTMLTableElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->caption()));
    return result;
}

JSValue jsHTMLTableElementTHead(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSHTMLTableElement* castedThis = static_cast<JSHTMLTableElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->tHead()));
    return result;
}

JSValue jsHTMLTableElementTFoot(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSHTMLTableElement* castedThis = static_cast<JSHTMLTableElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->tFoot()));
    return result;
}

JSValue jsHTMLTableElementRows(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSHTMLTableElement* castedThis = static_cast<JSHTMLTableElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->rows()));
    return result;
}

JSValue jsHTMLTableElementTBodies(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSHTMLTableElement* castedThis = static_cast<JSHTMLTableElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->tBodies()));
    return result;
}

JSValue jsHTMLTableElementAlign(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSHTMLTableElement* castedThis = static_cast<JSHTMLTableElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThis->impl());
    JSValue result = jsString(exec, imp->align());
    return result;
}

JSValue jsHTMLTableElementBgColor(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSHTMLTableElement* castedThis = static_cast<JSHTMLTableElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThis->impl());
    JSValue result = jsString(exec, imp->bgColor());
    return result;
}

JSValue jsHTMLTableElementBorder(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSHTMLTableElement* castedThis = static_cast<JSHTMLTableElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThis->impl());
    JSValue result = jsString(exec, imp->border());
    return result;
}

JSValue jsHTMLTableElementCellPadding(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSHTMLTableElement* castedThis = static_cast<JSHTMLTableElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThis->impl());
    JSValue result = jsString(exec, imp->cellPadding());
    return result;
}

JSValue jsHTMLTableElementCellSpacing(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSHTMLTableElement* castedThis = static_cast<JSHTMLTableElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThis->impl());
    JSValue result = jsString(exec, imp->cellSpacing());
    return result;
}

JSValue jsHTMLTableElementFrame(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSHTMLTableElement* castedThis = static_cast<JSHTMLTableElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThis->impl());
    JSValue result = jsString(exec, imp->frame());
    return result;
}

JSValue jsHTMLTableElementRules(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSHTMLTableElement* castedThis = static_cast<JSHTMLTableElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThis->impl());
    JSValue result = jsString(exec, imp->rules());
    return result;
}

JSValue jsHTMLTableElementSummary(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSHTMLTableElement* castedThis = static_cast<JSHTMLTableElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThis->impl());
    JSValue result = jsString(exec, imp->summary());
    return result;
}

JSValue jsHTMLTableElementWidth(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSHTMLTableElement* castedThis = static_cast<JSHTMLTableElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThis->impl());
    JSValue result = jsString(exec, imp->width());
    return result;
}

JSValue jsHTMLTableElementConstructor(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSHTMLTableElement* domObject = static_cast<JSHTMLTableElement*>(asObject(slotBase));
    return JSHTMLTableElement::getConstructor(exec, domObject->globalObject());
}
void JSHTMLTableElement::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
    lookupPut<JSHTMLTableElement, Base>(exec, propertyName, value, &JSHTMLTableElementTable, this, slot);
}

void setJSHTMLTableElementCaption(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSHTMLTableElement* castedThisObj = static_cast<JSHTMLTableElement*>(thisObject);
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThisObj->impl());
    ExceptionCode ec = 0;
    imp->setCaption(toHTMLTableCaptionElement(value), ec);
    setDOMException(exec, ec);
}

void setJSHTMLTableElementTHead(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSHTMLTableElement* castedThisObj = static_cast<JSHTMLTableElement*>(thisObject);
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThisObj->impl());
    ExceptionCode ec = 0;
    imp->setTHead(toHTMLTableSectionElement(value), ec);
    setDOMException(exec, ec);
}

void setJSHTMLTableElementTFoot(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSHTMLTableElement* castedThisObj = static_cast<JSHTMLTableElement*>(thisObject);
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThisObj->impl());
    ExceptionCode ec = 0;
    imp->setTFoot(toHTMLTableSectionElement(value), ec);
    setDOMException(exec, ec);
}

void setJSHTMLTableElementAlign(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSHTMLTableElement* castedThisObj = static_cast<JSHTMLTableElement*>(thisObject);
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThisObj->impl());
    imp->setAlign(valueToStringWithNullCheck(exec, value));
}

void setJSHTMLTableElementBgColor(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSHTMLTableElement* castedThisObj = static_cast<JSHTMLTableElement*>(thisObject);
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThisObj->impl());
    imp->setBgColor(valueToStringWithNullCheck(exec, value));
}

void setJSHTMLTableElementBorder(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSHTMLTableElement* castedThisObj = static_cast<JSHTMLTableElement*>(thisObject);
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThisObj->impl());
    imp->setBorder(valueToStringWithNullCheck(exec, value));
}

void setJSHTMLTableElementCellPadding(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSHTMLTableElement* castedThisObj = static_cast<JSHTMLTableElement*>(thisObject);
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThisObj->impl());
    imp->setCellPadding(valueToStringWithNullCheck(exec, value));
}

void setJSHTMLTableElementCellSpacing(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSHTMLTableElement* castedThisObj = static_cast<JSHTMLTableElement*>(thisObject);
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThisObj->impl());
    imp->setCellSpacing(valueToStringWithNullCheck(exec, value));
}

void setJSHTMLTableElementFrame(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSHTMLTableElement* castedThisObj = static_cast<JSHTMLTableElement*>(thisObject);
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThisObj->impl());
    imp->setFrame(valueToStringWithNullCheck(exec, value));
}

void setJSHTMLTableElementRules(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSHTMLTableElement* castedThisObj = static_cast<JSHTMLTableElement*>(thisObject);
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThisObj->impl());
    imp->setRules(valueToStringWithNullCheck(exec, value));
}

void setJSHTMLTableElementSummary(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSHTMLTableElement* castedThisObj = static_cast<JSHTMLTableElement*>(thisObject);
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThisObj->impl());
    imp->setSummary(valueToStringWithNullCheck(exec, value));
}

void setJSHTMLTableElementWidth(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSHTMLTableElement* castedThisObj = static_cast<JSHTMLTableElement*>(thisObject);
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThisObj->impl());
    imp->setWidth(valueToStringWithNullCheck(exec, value));
}

JSValue JSHTMLTableElement::getConstructor(ExecState* exec, JSGlobalObject* globalObject)
{
    return getDOMConstructor<JSHTMLTableElementConstructor>(exec, static_cast<JSDOMGlobalObject*>(globalObject));
}

JSValue JSC_HOST_CALL jsHTMLTableElementPrototypeFunctionCreateTHead(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSHTMLTableElement::s_info))
        return throwError(exec, TypeError);
    JSHTMLTableElement* castedThisObj = static_cast<JSHTMLTableElement*>(asObject(thisValue));
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThisObj->impl());


    JSC::JSValue result = toJS(exec, castedThisObj->globalObject(), WTF::getPtr(imp->createTHead()));
    return result;
}

JSValue JSC_HOST_CALL jsHTMLTableElementPrototypeFunctionDeleteTHead(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSHTMLTableElement::s_info))
        return throwError(exec, TypeError);
    JSHTMLTableElement* castedThisObj = static_cast<JSHTMLTableElement*>(asObject(thisValue));
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThisObj->impl());

    imp->deleteTHead();
    return jsUndefined();
}

JSValue JSC_HOST_CALL jsHTMLTableElementPrototypeFunctionCreateTFoot(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSHTMLTableElement::s_info))
        return throwError(exec, TypeError);
    JSHTMLTableElement* castedThisObj = static_cast<JSHTMLTableElement*>(asObject(thisValue));
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThisObj->impl());


    JSC::JSValue result = toJS(exec, castedThisObj->globalObject(), WTF::getPtr(imp->createTFoot()));
    return result;
}

JSValue JSC_HOST_CALL jsHTMLTableElementPrototypeFunctionDeleteTFoot(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSHTMLTableElement::s_info))
        return throwError(exec, TypeError);
    JSHTMLTableElement* castedThisObj = static_cast<JSHTMLTableElement*>(asObject(thisValue));
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThisObj->impl());

    imp->deleteTFoot();
    return jsUndefined();
}

JSValue JSC_HOST_CALL jsHTMLTableElementPrototypeFunctionCreateCaption(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSHTMLTableElement::s_info))
        return throwError(exec, TypeError);
    JSHTMLTableElement* castedThisObj = static_cast<JSHTMLTableElement*>(asObject(thisValue));
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThisObj->impl());


    JSC::JSValue result = toJS(exec, castedThisObj->globalObject(), WTF::getPtr(imp->createCaption()));
    return result;
}

JSValue JSC_HOST_CALL jsHTMLTableElementPrototypeFunctionDeleteCaption(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSHTMLTableElement::s_info))
        return throwError(exec, TypeError);
    JSHTMLTableElement* castedThisObj = static_cast<JSHTMLTableElement*>(asObject(thisValue));
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThisObj->impl());

    imp->deleteCaption();
    return jsUndefined();
}

JSValue JSC_HOST_CALL jsHTMLTableElementPrototypeFunctionInsertRow(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSHTMLTableElement::s_info))
        return throwError(exec, TypeError);
    JSHTMLTableElement* castedThisObj = static_cast<JSHTMLTableElement*>(asObject(thisValue));
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThisObj->impl());
    ExceptionCode ec = 0;
    int index = args.at(0).toInt32(exec);


    JSC::JSValue result = toJS(exec, castedThisObj->globalObject(), WTF::getPtr(imp->insertRow(index, ec)));
    setDOMException(exec, ec);
    return result;
}

JSValue JSC_HOST_CALL jsHTMLTableElementPrototypeFunctionDeleteRow(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSHTMLTableElement::s_info))
        return throwError(exec, TypeError);
    JSHTMLTableElement* castedThisObj = static_cast<JSHTMLTableElement*>(asObject(thisValue));
    HTMLTableElement* imp = static_cast<HTMLTableElement*>(castedThisObj->impl());
    ExceptionCode ec = 0;
    int index = args.at(0).toInt32(exec);

    imp->deleteRow(index, ec);
    setDOMException(exec, ec);
    return jsUndefined();
}


}
