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

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

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

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

#include "config.h"

#if ENABLE(SHARED_WORKERS)

#include "JSSharedWorker.h"

#include "JSMessagePort.h"
#include "MessagePort.h"
#include "SharedWorker.h"
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

ASSERT_CLASS_FITS_IN_CELL(JSSharedWorker);

/* Hash table */

static const HashTableValue JSSharedWorkerTableValues[2] =
{
    { "port", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSharedWorkerPort), (intptr_t)0 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSSharedWorkerTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 0, JSSharedWorkerTableValues, 0 };
#else
    { 2, 1, JSSharedWorkerTableValues, 0 };
#endif

/* Hash table for prototype */

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

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

const ClassInfo JSSharedWorkerPrototype::s_info = { "SharedWorkerPrototype", 0, &JSSharedWorkerPrototypeTable, 0 };

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

const ClassInfo JSSharedWorker::s_info = { "SharedWorker", &JSAbstractWorker::s_info, &JSSharedWorkerTable, 0 };

JSSharedWorker::JSSharedWorker(NonNullPassRefPtr<Structure> structure, JSDOMGlobalObject* globalObject, PassRefPtr<SharedWorker> impl)
    : JSAbstractWorker(structure, globalObject, impl)
{
}

JSObject* JSSharedWorker::createPrototype(ExecState* exec, JSGlobalObject* globalObject)
{
    return new (exec) JSSharedWorkerPrototype(JSSharedWorkerPrototype::createStructure(JSAbstractWorkerPrototype::self(exec, globalObject)));
}

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

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

JSValue jsSharedWorkerPort(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSharedWorker* castedThis = static_cast<JSSharedWorker*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    SharedWorker* imp = static_cast<SharedWorker*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->port()));
    return result;
}

JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, SharedWorker* object)
{
    return getDOMObjectWrapper<JSSharedWorker>(exec, globalObject, object);
}
SharedWorker* toSharedWorker(JSC::JSValue value)
{
    return value.inherits(&JSSharedWorker::s_info) ? static_cast<JSSharedWorker*>(asObject(value))->impl() : 0;
}

}

#endif // ENABLE(SHARED_WORKERS)
