/*
    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(MEDIA_STREAM)

#include "JSMediaTrackConstraintSet.h"

#include "JSDOMBinding.h"
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

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

/* Hash table for prototype */
const ClassInfo JSMediaTrackConstraintSetPrototype::s_info = { "MediaTrackConstraintSetPrototype", &Base::s_info, 0, CREATE_METHOD_TABLE(JSMediaTrackConstraintSetPrototype) };

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

JSMediaTrackConstraintSet::JSMediaTrackConstraintSet(Structure* structure, JSDOMGlobalObject& globalObject, Ref<MediaTrackConstraintSet>&& impl)
    : JSDOMWrapper<MediaTrackConstraintSet>(structure, globalObject, WTFMove(impl))
{
}

JSObject* JSMediaTrackConstraintSet::createPrototype(VM& vm, JSGlobalObject* globalObject)
{
    return JSMediaTrackConstraintSetPrototype::create(vm, globalObject, JSMediaTrackConstraintSetPrototype::createStructure(vm, globalObject, globalObject->objectPrototype()));
}

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

void JSMediaTrackConstraintSet::destroy(JSC::JSCell* cell)
{
    JSMediaTrackConstraintSet* thisObject = static_cast<JSMediaTrackConstraintSet*>(cell);
    thisObject->JSMediaTrackConstraintSet::~JSMediaTrackConstraintSet();
}

bool JSMediaTrackConstraintSetOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
{
    UNUSED_PARAM(handle);
    UNUSED_PARAM(visitor);
    return false;
}

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

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

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

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

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

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

}

#endif // ENABLE(MEDIA_STREAM)
