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

#include "JSRTCPeerConnection.h"

#include "Dictionary.h"
#include "Document.h"
#include "EventNames.h"
#include "ExceptionCode.h"
#include "JSDOMBinding.h"
#include "JSDOMConstructor.h"
#include "JSDOMConvert.h"
#include "JSDOMPromise.h"
#include "JSEventListener.h"
#include "JSMediaStream.h"
#include "JSMediaStreamTrack.h"
#include "JSRTCConfiguration.h"
#include "JSRTCDataChannel.h"
#include "JSRTCIceCandidate.h"
#include "JSRTCRtpReceiver.h"
#include "JSRTCRtpSender.h"
#include "JSRTCRtpTransceiver.h"
#include "JSRTCSessionDescription.h"
#include "MediaStream.h"
#include "RTCConfiguration.h"
#include "RTCDataChannel.h"
#include "RTCPeerConnectionBuiltins.h"
#include "RTCRtpReceiver.h"
#include "RTCRtpSender.h"
#include "RTCRtpTransceiver.h"
#include "URL.h"
#include "WebCoreJSClientData.h"
#include <runtime/Error.h>
#include <runtime/JSArray.h>
#include <runtime/JSString.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

template<typename T> Optional<T> parse(ExecState&, JSValue);
template<typename T> const char* expectedEnumerationValues();

JSString* jsStringWithCache(ExecState*, RTCPeerConnection::RtpTransceiverDirection);

JSString* jsStringWithCache(ExecState* state, RTCPeerConnection::RtpTransceiverDirection enumerationValue)
{
    static NeverDestroyed<const String> values[] = {
        ASCIILiteral("sendrecv"),
        ASCIILiteral("sendonly"),
        ASCIILiteral("recvonly"),
        ASCIILiteral("inactive"),
    };
    static_assert(static_cast<size_t>(RTCPeerConnection::RtpTransceiverDirection::Sendrecv) == 0, "RTCPeerConnection::RtpTransceiverDirection::Sendrecv is not 0 as expected");
    static_assert(static_cast<size_t>(RTCPeerConnection::RtpTransceiverDirection::Sendonly) == 1, "RTCPeerConnection::RtpTransceiverDirection::Sendonly is not 1 as expected");
    static_assert(static_cast<size_t>(RTCPeerConnection::RtpTransceiverDirection::Recvonly) == 2, "RTCPeerConnection::RtpTransceiverDirection::Recvonly is not 2 as expected");
    static_assert(static_cast<size_t>(RTCPeerConnection::RtpTransceiverDirection::Inactive) == 3, "RTCPeerConnection::RtpTransceiverDirection::Inactive is not 3 as expected");
    ASSERT(static_cast<size_t>(enumerationValue) < WTF_ARRAY_LENGTH(values));
    return jsStringWithCache(state, values[static_cast<size_t>(enumerationValue)]);
}

template<> struct JSValueTraits<RTCPeerConnection::RtpTransceiverDirection> {
    static JSString* arrayJSValue(ExecState* state, JSDOMGlobalObject*, RTCPeerConnection::RtpTransceiverDirection value) { return jsStringWithCache(state, value); }
};

template<> Optional<RTCPeerConnection::RtpTransceiverDirection> parse<RTCPeerConnection::RtpTransceiverDirection>(ExecState& state, JSValue value)
{
    auto stringValue = value.toWTFString(&state);
    if (stringValue == "sendrecv")
        return RTCPeerConnection::RtpTransceiverDirection::Sendrecv;
    if (stringValue == "sendonly")
        return RTCPeerConnection::RtpTransceiverDirection::Sendonly;
    if (stringValue == "recvonly")
        return RTCPeerConnection::RtpTransceiverDirection::Recvonly;
    if (stringValue == "inactive")
        return RTCPeerConnection::RtpTransceiverDirection::Inactive;
    return Nullopt;
}

template<> RTCPeerConnection::RtpTransceiverDirection convert<RTCPeerConnection::RtpTransceiverDirection>(ExecState& state, JSValue value)
{
    VM& vm = state.vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    auto result = parse<RTCPeerConnection::RtpTransceiverDirection>(state, value);
    if (UNLIKELY(!result)) {
        throwTypeError(&state, throwScope);
        return { };
    }
    return result.value();
}

template<> inline const char* expectedEnumerationValues<RTCPeerConnection::RtpTransceiverDirection>()
{
    return "\"sendrecv\", \"sendonly\", \"recvonly\", \"inactive\"";
}

template<> Optional<RTCPeerConnection::RtpTransceiverInit> convertDictionary<RTCPeerConnection::RtpTransceiverInit>(ExecState& state, JSValue value)
{
    VM& vm = state.vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    if (value.isUndefinedOrNull())
        return RTCPeerConnection::RtpTransceiverInit { RTCPeerConnection::RtpTransceiverDirection::Sendrecv };
    auto* object = value.getObject();
    if (UNLIKELY(!object || object->type() == RegExpObjectType)) {
        throwTypeError(&state, throwScope);
        return Nullopt;
    }
    auto direction = convertOptional<RTCPeerConnection::RtpTransceiverDirection>(state, object->get(&state, Identifier::fromString(&state, "direction")), RTCPeerConnection::RtpTransceiverDirection::Sendrecv);
    return RTCPeerConnection::RtpTransceiverInit { WTFMove(direction) };
}

// Functions

JSC::EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionInitializeWith(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionGetSenders(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionGetReceivers(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionGetTransceivers(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionAddTrack(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionRemoveTrack(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionAddTransceiver(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionGetRemoteStreams(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionGetConfiguration(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionSetConfiguration(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionQueuedCreateOffer(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionQueuedCreateAnswer(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionQueuedSetLocalDescription(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionQueuedSetRemoteDescription(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionQueuedAddIceCandidate(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionPrivateGetStats(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionCreateDataChannel(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionClose(JSC::ExecState*);

// Attributes

JSC::EncodedJSValue jsRTCPeerConnectionLocalDescription(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsRTCPeerConnectionCurrentLocalDescription(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsRTCPeerConnectionPendingLocalDescription(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsRTCPeerConnectionRemoteDescription(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsRTCPeerConnectionCurrentRemoteDescription(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsRTCPeerConnectionPendingRemoteDescription(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsRTCPeerConnectionSignalingState(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsRTCPeerConnectionIceGatheringState(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsRTCPeerConnectionIceConnectionState(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsRTCPeerConnectionOnnegotiationneeded(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSRTCPeerConnectionOnnegotiationneeded(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsRTCPeerConnectionOnicecandidate(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSRTCPeerConnectionOnicecandidate(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsRTCPeerConnectionOnsignalingstatechange(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSRTCPeerConnectionOnsignalingstatechange(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsRTCPeerConnectionOntrack(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSRTCPeerConnectionOntrack(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsRTCPeerConnectionOniceconnectionstatechange(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSRTCPeerConnectionOniceconnectionstatechange(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsRTCPeerConnectionOnicegatheringstatechange(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSRTCPeerConnectionOnicegatheringstatechange(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsRTCPeerConnectionOndatachannel(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSRTCPeerConnectionOndatachannel(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsRTCPeerConnectionOnaddstream(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSRTCPeerConnectionOnaddstream(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsRTCPeerConnectionConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSRTCPeerConnectionConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);

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

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

typedef JSBuiltinConstructor<JSRTCPeerConnection> JSRTCPeerConnectionConstructor;

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

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

template<> FunctionExecutable* JSRTCPeerConnectionConstructor::initializeExecutable(VM& vm)
{
    return rtcPeerConnectionInitializeRTCPeerConnectionCodeGenerator(vm);
}

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

/* Hash table for prototype */

static const HashTableValue JSRTCPeerConnectionPrototypeTableValues[] =
{
    { "constructor", DontEnum, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsRTCPeerConnectionConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSRTCPeerConnectionConstructor) } },
    { "localDescription", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsRTCPeerConnectionLocalDescription), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "currentLocalDescription", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsRTCPeerConnectionCurrentLocalDescription), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "pendingLocalDescription", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsRTCPeerConnectionPendingLocalDescription), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "remoteDescription", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsRTCPeerConnectionRemoteDescription), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "currentRemoteDescription", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsRTCPeerConnectionCurrentRemoteDescription), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "pendingRemoteDescription", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsRTCPeerConnectionPendingRemoteDescription), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "signalingState", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsRTCPeerConnectionSignalingState), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "iceGatheringState", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsRTCPeerConnectionIceGatheringState), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "iceConnectionState", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsRTCPeerConnectionIceConnectionState), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "onnegotiationneeded", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsRTCPeerConnectionOnnegotiationneeded), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSRTCPeerConnectionOnnegotiationneeded) } },
    { "onicecandidate", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsRTCPeerConnectionOnicecandidate), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSRTCPeerConnectionOnicecandidate) } },
    { "onsignalingstatechange", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsRTCPeerConnectionOnsignalingstatechange), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSRTCPeerConnectionOnsignalingstatechange) } },
    { "ontrack", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsRTCPeerConnectionOntrack), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSRTCPeerConnectionOntrack) } },
    { "oniceconnectionstatechange", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsRTCPeerConnectionOniceconnectionstatechange), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSRTCPeerConnectionOniceconnectionstatechange) } },
    { "onicegatheringstatechange", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsRTCPeerConnectionOnicegatheringstatechange), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSRTCPeerConnectionOnicegatheringstatechange) } },
    { "ondatachannel", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsRTCPeerConnectionOndatachannel), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSRTCPeerConnectionOndatachannel) } },
    { "onaddstream", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsRTCPeerConnectionOnaddstream), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSRTCPeerConnectionOnaddstream) } },
    { "getSenders", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsRTCPeerConnectionPrototypeFunctionGetSenders), (intptr_t) (0) } },
    { "getReceivers", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsRTCPeerConnectionPrototypeFunctionGetReceivers), (intptr_t) (0) } },
    { "getTransceivers", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsRTCPeerConnectionPrototypeFunctionGetTransceivers), (intptr_t) (0) } },
    { "addTrack", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsRTCPeerConnectionPrototypeFunctionAddTrack), (intptr_t) (1) } },
    { "removeTrack", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsRTCPeerConnectionPrototypeFunctionRemoveTrack), (intptr_t) (1) } },
    { "addTransceiver", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsRTCPeerConnectionPrototypeFunctionAddTransceiver), (intptr_t) (1) } },
    { "getLocalStreams", JSC::Builtin, NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(rtcPeerConnectionGetLocalStreamsCodeGenerator), (intptr_t) (0) } },
    { "getRemoteStreams", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsRTCPeerConnectionPrototypeFunctionGetRemoteStreams), (intptr_t) (0) } },
    { "getStreamById", JSC::Builtin, NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(rtcPeerConnectionGetStreamByIdCodeGenerator), (intptr_t) (1) } },
    { "addStream", JSC::Builtin, NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(rtcPeerConnectionAddStreamCodeGenerator), (intptr_t) (1) } },
    { "removeStream", JSC::Builtin, NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(rtcPeerConnectionRemoveStreamCodeGenerator), (intptr_t) (1) } },
    { "createOffer", JSC::Builtin, NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(rtcPeerConnectionCreateOfferCodeGenerator), (intptr_t) (0) } },
    { "createAnswer", JSC::Builtin, NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(rtcPeerConnectionCreateAnswerCodeGenerator), (intptr_t) (0) } },
    { "setLocalDescription", JSC::Builtin, NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(rtcPeerConnectionSetLocalDescriptionCodeGenerator), (intptr_t) (1) } },
    { "setRemoteDescription", JSC::Builtin, NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(rtcPeerConnectionSetRemoteDescriptionCodeGenerator), (intptr_t) (1) } },
    { "addIceCandidate", JSC::Builtin, NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(rtcPeerConnectionAddIceCandidateCodeGenerator), (intptr_t) (1) } },
    { "getConfiguration", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsRTCPeerConnectionPrototypeFunctionGetConfiguration), (intptr_t) (0) } },
    { "setConfiguration", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsRTCPeerConnectionPrototypeFunctionSetConfiguration), (intptr_t) (1) } },
    { "getStats", JSC::Builtin, NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(rtcPeerConnectionGetStatsCodeGenerator), (intptr_t) (0) } },
    { "createDataChannel", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsRTCPeerConnectionPrototypeFunctionCreateDataChannel), (intptr_t) (1) } },
    { "close", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsRTCPeerConnectionPrototypeFunctionClose), (intptr_t) (0) } },
};

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

void JSRTCPeerConnectionPrototype::finishCreation(VM& vm)
{
    Base::finishCreation(vm);
    reifyStaticProperties(vm, JSRTCPeerConnectionPrototypeTableValues, *this);
    JSVMClientData& clientData = *static_cast<JSVMClientData*>(vm.clientData);
    putDirect(vm, clientData.builtinNames().initializeWithPrivateName(), JSFunction::create(vm, globalObject(), 0, String(), jsRTCPeerConnectionPrototypeFunctionInitializeWith), ReadOnly | DontEnum);
    putDirect(vm, clientData.builtinNames().getSendersPrivateName(), JSFunction::create(vm, globalObject(), 0, String(), jsRTCPeerConnectionPrototypeFunctionGetSenders), ReadOnly | DontEnum);
    putDirect(vm, clientData.builtinNames().addTrackPrivateName(), JSFunction::create(vm, globalObject(), 0, String(), jsRTCPeerConnectionPrototypeFunctionAddTrack), ReadOnly | DontEnum);
    putDirect(vm, clientData.builtinNames().removeTrackPrivateName(), JSFunction::create(vm, globalObject(), 0, String(), jsRTCPeerConnectionPrototypeFunctionRemoveTrack), ReadOnly | DontEnum);
    putDirect(vm, clientData.builtinNames().getRemoteStreamsPrivateName(), JSFunction::create(vm, globalObject(), 0, String(), jsRTCPeerConnectionPrototypeFunctionGetRemoteStreams), ReadOnly | DontEnum);
    putDirect(vm, clientData.builtinNames().queuedCreateOfferPrivateName(), JSFunction::create(vm, globalObject(), 0, String(), jsRTCPeerConnectionPrototypeFunctionQueuedCreateOffer), ReadOnly | DontEnum);
    putDirect(vm, clientData.builtinNames().queuedCreateAnswerPrivateName(), JSFunction::create(vm, globalObject(), 0, String(), jsRTCPeerConnectionPrototypeFunctionQueuedCreateAnswer), ReadOnly | DontEnum);
    putDirect(vm, clientData.builtinNames().queuedSetLocalDescriptionPrivateName(), JSFunction::create(vm, globalObject(), 0, String(), jsRTCPeerConnectionPrototypeFunctionQueuedSetLocalDescription), ReadOnly | DontEnum);
    putDirect(vm, clientData.builtinNames().queuedSetRemoteDescriptionPrivateName(), JSFunction::create(vm, globalObject(), 0, String(), jsRTCPeerConnectionPrototypeFunctionQueuedSetRemoteDescription), ReadOnly | DontEnum);
    putDirect(vm, clientData.builtinNames().queuedAddIceCandidatePrivateName(), JSFunction::create(vm, globalObject(), 0, String(), jsRTCPeerConnectionPrototypeFunctionQueuedAddIceCandidate), ReadOnly | DontEnum);
    putDirect(vm, clientData.builtinNames().privateGetStatsPrivateName(), JSFunction::create(vm, globalObject(), 0, String(), jsRTCPeerConnectionPrototypeFunctionPrivateGetStats), ReadOnly | DontEnum);
}

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

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

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

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

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


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


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


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


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


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


EncodedJSValue jsRTCPeerConnectionSignalingState(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<JSRTCPeerConnection*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "webkitRTCPeerConnection", "signalingState");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.signalingState());
    return JSValue::encode(result);
}


EncodedJSValue jsRTCPeerConnectionIceGatheringState(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<JSRTCPeerConnection*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "webkitRTCPeerConnection", "iceGatheringState");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.iceGatheringState());
    return JSValue::encode(result);
}


EncodedJSValue jsRTCPeerConnectionIceConnectionState(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<JSRTCPeerConnection*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "webkitRTCPeerConnection", "iceConnectionState");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.iceConnectionState());
    return JSValue::encode(result);
}


EncodedJSValue jsRTCPeerConnectionOnnegotiationneeded(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<JSRTCPeerConnection*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "webkitRTCPeerConnection", "onnegotiationneeded");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().negotiationneededEvent));
}


EncodedJSValue jsRTCPeerConnectionOnicecandidate(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<JSRTCPeerConnection*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "webkitRTCPeerConnection", "onicecandidate");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().icecandidateEvent));
}


EncodedJSValue jsRTCPeerConnectionOnsignalingstatechange(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<JSRTCPeerConnection*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "webkitRTCPeerConnection", "onsignalingstatechange");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().signalingstatechangeEvent));
}


EncodedJSValue jsRTCPeerConnectionOntrack(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<JSRTCPeerConnection*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "webkitRTCPeerConnection", "ontrack");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().trackEvent));
}


EncodedJSValue jsRTCPeerConnectionOniceconnectionstatechange(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<JSRTCPeerConnection*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "webkitRTCPeerConnection", "oniceconnectionstatechange");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().iceconnectionstatechangeEvent));
}


EncodedJSValue jsRTCPeerConnectionOnicegatheringstatechange(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<JSRTCPeerConnection*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "webkitRTCPeerConnection", "onicegatheringstatechange");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().icegatheringstatechangeEvent));
}


EncodedJSValue jsRTCPeerConnectionOndatachannel(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<JSRTCPeerConnection*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "webkitRTCPeerConnection", "ondatachannel");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().datachannelEvent));
}


EncodedJSValue jsRTCPeerConnectionOnaddstream(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<JSRTCPeerConnection*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "webkitRTCPeerConnection", "onaddstream");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().addstreamEvent));
}


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

bool setJSRTCPeerConnectionConstructor(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    JSValue value = JSValue::decode(encodedValue);
    JSRTCPeerConnectionPrototype* domObject = jsDynamicCast<JSRTCPeerConnectionPrototype*>(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 setJSRTCPeerConnectionOnnegotiationneeded(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);
    JSRTCPeerConnection* castedThis = jsDynamicCast<JSRTCPeerConnection*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "webkitRTCPeerConnection", "onnegotiationneeded");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().negotiationneededEvent, value);
    return true;
}


bool setJSRTCPeerConnectionOnicecandidate(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);
    JSRTCPeerConnection* castedThis = jsDynamicCast<JSRTCPeerConnection*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "webkitRTCPeerConnection", "onicecandidate");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().icecandidateEvent, value);
    return true;
}


bool setJSRTCPeerConnectionOnsignalingstatechange(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);
    JSRTCPeerConnection* castedThis = jsDynamicCast<JSRTCPeerConnection*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "webkitRTCPeerConnection", "onsignalingstatechange");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().signalingstatechangeEvent, value);
    return true;
}


bool setJSRTCPeerConnectionOntrack(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);
    JSRTCPeerConnection* castedThis = jsDynamicCast<JSRTCPeerConnection*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "webkitRTCPeerConnection", "ontrack");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().trackEvent, value);
    return true;
}


bool setJSRTCPeerConnectionOniceconnectionstatechange(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);
    JSRTCPeerConnection* castedThis = jsDynamicCast<JSRTCPeerConnection*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "webkitRTCPeerConnection", "oniceconnectionstatechange");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().iceconnectionstatechangeEvent, value);
    return true;
}


bool setJSRTCPeerConnectionOnicegatheringstatechange(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);
    JSRTCPeerConnection* castedThis = jsDynamicCast<JSRTCPeerConnection*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "webkitRTCPeerConnection", "onicegatheringstatechange");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().icegatheringstatechangeEvent, value);
    return true;
}


bool setJSRTCPeerConnectionOndatachannel(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);
    JSRTCPeerConnection* castedThis = jsDynamicCast<JSRTCPeerConnection*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "webkitRTCPeerConnection", "ondatachannel");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().datachannelEvent, value);
    return true;
}


bool setJSRTCPeerConnectionOnaddstream(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);
    JSRTCPeerConnection* castedThis = jsDynamicCast<JSRTCPeerConnection*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "webkitRTCPeerConnection", "onaddstream");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().addstreamEvent, value);
    return true;
}


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

EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionInitializeWith(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSRTCPeerConnection*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitRTCPeerConnection", "initializeWith");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSRTCPeerConnection::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto* context = jsCast<JSDOMGlobalObject*>(state->lexicalGlobalObject())->scriptExecutionContext();
    if (!context)
        return JSValue::encode(jsUndefined());
    ASSERT(context->isDocument());
    auto& document = downcast<Document>(*context);
    auto parameters = Dictionary(state, state->uncheckedArgument(0));
    impl.initializeWith(document, WTFMove(parameters), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionGetSenders(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSRTCPeerConnection*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitRTCPeerConnection", "getSenders");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSRTCPeerConnection::info());
    auto& impl = castedThis->wrapped();
    JSValue result = jsArray(state, castedThis->globalObject(), impl.getSenders());
    return JSValue::encode(result);
}

EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionGetReceivers(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSRTCPeerConnection*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitRTCPeerConnection", "getReceivers");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSRTCPeerConnection::info());
    auto& impl = castedThis->wrapped();
    JSValue result = jsArray(state, castedThis->globalObject(), impl.getReceivers());
    return JSValue::encode(result);
}

EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionGetTransceivers(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSRTCPeerConnection*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitRTCPeerConnection", "getTransceivers");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSRTCPeerConnection::info());
    auto& impl = castedThis->wrapped();
    JSValue result = jsArray(state, castedThis->globalObject(), impl.getTransceivers());
    return JSValue::encode(result);
}

EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionAddTrack(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSRTCPeerConnection*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitRTCPeerConnection", "addTrack");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSRTCPeerConnection::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto track = JSMediaStreamTrack::toWrapped(state->uncheckedArgument(0));
    if (UNLIKELY(!track))
        return throwArgumentTypeError(*state, throwScope, 0, "track", "webkitRTCPeerConnection", "addTrack", "MediaStreamTrack");
    auto streams = toArguments<VariadicHelper<JSMediaStream, MediaStream>>(*state, 1);
    if (!streams.arguments)
        return throwArgumentTypeError(*state, throwScope, streams.argumentIndex, "streams", "webkitRTCPeerConnection", "addTrack", "MediaStream");
    JSValue result = toJS(state, castedThis->globalObject(), impl.addTrack(*track, WTFMove(streams.arguments.value()), ec));

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

EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionRemoveTrack(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSRTCPeerConnection*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitRTCPeerConnection", "removeTrack");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSRTCPeerConnection::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto sender = JSRTCRtpSender::toWrapped(state->uncheckedArgument(0));
    if (UNLIKELY(!sender))
        return throwArgumentTypeError(*state, throwScope, 0, "sender", "webkitRTCPeerConnection", "removeTrack", "RTCRtpSender");
    impl.removeTrack(*sender, ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

static inline EncodedJSValue jsRTCPeerConnectionPrototypeFunctionAddTransceiver1(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSRTCPeerConnection*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitRTCPeerConnection", "addTransceiver");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSRTCPeerConnection::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto track = JSMediaStreamTrack::toWrapped(state->uncheckedArgument(0));
    if (UNLIKELY(!track))
        return throwArgumentTypeError(*state, throwScope, 0, "track", "webkitRTCPeerConnection", "addTransceiver", "MediaStreamTrack");
    auto init = state->argument(1).isUndefined() ? RTCPeerConnection::RtpTransceiverInit() : convertDictionary<RTCPeerConnection::RtpTransceiverInit>(*state, state->uncheckedArgument(1));
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    JSValue result = toJS(state, castedThis->globalObject(), impl.addTransceiver(*track, init.value(), ec));

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

static inline EncodedJSValue jsRTCPeerConnectionPrototypeFunctionAddTransceiver2(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSRTCPeerConnection*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitRTCPeerConnection", "addTransceiver");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSRTCPeerConnection::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto kind = state->uncheckedArgument(0).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    auto init = state->argument(1).isUndefined() ? RTCPeerConnection::RtpTransceiverInit() : convertDictionary<RTCPeerConnection::RtpTransceiverInit>(*state, state->uncheckedArgument(1));
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    JSValue result = toJS(state, castedThis->globalObject(), impl.addTransceiver(WTFMove(kind), init.value(), ec));

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

EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionAddTransceiver(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    size_t argsCount = std::min<size_t>(2, state->argumentCount());
    if (argsCount == 1) {
        JSValue distinguishingArg = state->uncheckedArgument(0);
        if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits(JSMediaStreamTrack::info()))
            return jsRTCPeerConnectionPrototypeFunctionAddTransceiver1(state);
        return jsRTCPeerConnectionPrototypeFunctionAddTransceiver2(state);
    }
    if (argsCount == 2) {
        JSValue distinguishingArg = state->uncheckedArgument(0);
        if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits(JSMediaStreamTrack::info()))
            return jsRTCPeerConnectionPrototypeFunctionAddTransceiver1(state);
        return jsRTCPeerConnectionPrototypeFunctionAddTransceiver2(state);
    }
    return argsCount < 1 ? throwVMError(state, throwScope, createNotEnoughArgumentsError(state)) : throwVMTypeError(state, throwScope);
}

EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionGetRemoteStreams(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSRTCPeerConnection*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitRTCPeerConnection", "getRemoteStreams");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSRTCPeerConnection::info());
    auto& impl = castedThis->wrapped();
    JSValue result = jsArray(state, castedThis->globalObject(), impl.getRemoteStreams());
    return JSValue::encode(result);
}

EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionGetConfiguration(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSRTCPeerConnection*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitRTCPeerConnection", "getConfiguration");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSRTCPeerConnection::info());
    auto& impl = castedThis->wrapped();
    JSValue result = toJS(state, castedThis->globalObject(), impl.getConfiguration());
    return JSValue::encode(result);
}

EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionSetConfiguration(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSRTCPeerConnection*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitRTCPeerConnection", "setConfiguration");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSRTCPeerConnection::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto configuration = Dictionary(state, state->uncheckedArgument(0));
    impl.setConfiguration(WTFMove(configuration), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

static EncodedJSValue jsRTCPeerConnectionPrototypeFunctionQueuedCreateOfferPromise(ExecState*, Ref<DeferredPromise>&&);

EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionQueuedCreateOffer(ExecState* state)
{
    ASSERT(state);
    return JSValue::encode(callPromiseFunction<jsRTCPeerConnectionPrototypeFunctionQueuedCreateOfferPromise, PromiseExecutionScope::WindowOnly>(*state));
}

static inline EncodedJSValue jsRTCPeerConnectionPrototypeFunctionQueuedCreateOfferPromise(ExecState* state, Ref<DeferredPromise>&& promise)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSRTCPeerConnection*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitRTCPeerConnection", "queuedCreateOffer");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSRTCPeerConnection::info());
    auto& impl = castedThis->wrapped();
    auto offerOptions = Dictionary(state, state->argument(0));
    impl.queuedCreateOffer(WTFMove(offerOptions), WTFMove(promise));
    return JSValue::encode(jsUndefined());
}

static EncodedJSValue jsRTCPeerConnectionPrototypeFunctionQueuedCreateAnswerPromise(ExecState*, Ref<DeferredPromise>&&);

EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionQueuedCreateAnswer(ExecState* state)
{
    ASSERT(state);
    return JSValue::encode(callPromiseFunction<jsRTCPeerConnectionPrototypeFunctionQueuedCreateAnswerPromise, PromiseExecutionScope::WindowOnly>(*state));
}

static inline EncodedJSValue jsRTCPeerConnectionPrototypeFunctionQueuedCreateAnswerPromise(ExecState* state, Ref<DeferredPromise>&& promise)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSRTCPeerConnection*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitRTCPeerConnection", "queuedCreateAnswer");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSRTCPeerConnection::info());
    auto& impl = castedThis->wrapped();
    auto answerOptions = Dictionary(state, state->argument(0));
    impl.queuedCreateAnswer(WTFMove(answerOptions), WTFMove(promise));
    return JSValue::encode(jsUndefined());
}

static EncodedJSValue jsRTCPeerConnectionPrototypeFunctionQueuedSetLocalDescriptionPromise(ExecState*, Ref<DeferredPromise>&&);

EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionQueuedSetLocalDescription(ExecState* state)
{
    ASSERT(state);
    return JSValue::encode(callPromiseFunction<jsRTCPeerConnectionPrototypeFunctionQueuedSetLocalDescriptionPromise, PromiseExecutionScope::WindowOnly>(*state));
}

static inline EncodedJSValue jsRTCPeerConnectionPrototypeFunctionQueuedSetLocalDescriptionPromise(ExecState* state, Ref<DeferredPromise>&& promise)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSRTCPeerConnection*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitRTCPeerConnection", "queuedSetLocalDescription");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSRTCPeerConnection::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    auto description = JSRTCSessionDescription::toWrapped(state->uncheckedArgument(0));
    if (UNLIKELY(!description))
        return throwArgumentTypeError(*state, throwScope, 0, "description", "webkitRTCPeerConnection", "queuedSetLocalDescription", "RTCSessionDescription");
    impl.queuedSetLocalDescription(*description, WTFMove(promise));
    return JSValue::encode(jsUndefined());
}

static EncodedJSValue jsRTCPeerConnectionPrototypeFunctionQueuedSetRemoteDescriptionPromise(ExecState*, Ref<DeferredPromise>&&);

EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionQueuedSetRemoteDescription(ExecState* state)
{
    ASSERT(state);
    return JSValue::encode(callPromiseFunction<jsRTCPeerConnectionPrototypeFunctionQueuedSetRemoteDescriptionPromise, PromiseExecutionScope::WindowOnly>(*state));
}

static inline EncodedJSValue jsRTCPeerConnectionPrototypeFunctionQueuedSetRemoteDescriptionPromise(ExecState* state, Ref<DeferredPromise>&& promise)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSRTCPeerConnection*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitRTCPeerConnection", "queuedSetRemoteDescription");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSRTCPeerConnection::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    auto description = JSRTCSessionDescription::toWrapped(state->uncheckedArgument(0));
    if (UNLIKELY(!description))
        return throwArgumentTypeError(*state, throwScope, 0, "description", "webkitRTCPeerConnection", "queuedSetRemoteDescription", "RTCSessionDescription");
    impl.queuedSetRemoteDescription(*description, WTFMove(promise));
    return JSValue::encode(jsUndefined());
}

static EncodedJSValue jsRTCPeerConnectionPrototypeFunctionQueuedAddIceCandidatePromise(ExecState*, Ref<DeferredPromise>&&);

EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionQueuedAddIceCandidate(ExecState* state)
{
    ASSERT(state);
    return JSValue::encode(callPromiseFunction<jsRTCPeerConnectionPrototypeFunctionQueuedAddIceCandidatePromise, PromiseExecutionScope::WindowOnly>(*state));
}

static inline EncodedJSValue jsRTCPeerConnectionPrototypeFunctionQueuedAddIceCandidatePromise(ExecState* state, Ref<DeferredPromise>&& promise)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSRTCPeerConnection*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitRTCPeerConnection", "queuedAddIceCandidate");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSRTCPeerConnection::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    auto candidate = JSRTCIceCandidate::toWrapped(state->uncheckedArgument(0));
    if (UNLIKELY(!candidate))
        return throwArgumentTypeError(*state, throwScope, 0, "candidate", "webkitRTCPeerConnection", "queuedAddIceCandidate", "RTCIceCandidate");
    impl.queuedAddIceCandidate(*candidate, WTFMove(promise));
    return JSValue::encode(jsUndefined());
}

static EncodedJSValue jsRTCPeerConnectionPrototypeFunctionPrivateGetStatsPromise(ExecState*, Ref<DeferredPromise>&&);

EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionPrivateGetStats(ExecState* state)
{
    ASSERT(state);
    return JSValue::encode(callPromiseFunction<jsRTCPeerConnectionPrototypeFunctionPrivateGetStatsPromise, PromiseExecutionScope::WindowOnly>(*state));
}

static inline EncodedJSValue jsRTCPeerConnectionPrototypeFunctionPrivateGetStatsPromise(ExecState* state, Ref<DeferredPromise>&& promise)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSRTCPeerConnection*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitRTCPeerConnection", "privateGetStats");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSRTCPeerConnection::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    MediaStreamTrack* selector = nullptr;
    if (!state->uncheckedArgument(0).isUndefinedOrNull()) {
        selector = JSMediaStreamTrack::toWrapped(state->uncheckedArgument(0));
        if (UNLIKELY(!selector))
            return throwArgumentTypeError(*state, throwScope, 0, "selector", "webkitRTCPeerConnection", "privateGetStats", "MediaStreamTrack");
    }
    impl.privateGetStats(WTFMove(selector), WTFMove(promise));
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsRTCPeerConnectionPrototypeFunctionCreateDataChannel(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSRTCPeerConnection*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitRTCPeerConnection", "createDataChannel");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSRTCPeerConnection::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto label = valueToStringTreatingNullAsEmptyString(state, state->uncheckedArgument(0));
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    auto options = Dictionary(state, state->argument(1));
    JSValue result = toJS(state, castedThis->globalObject(), impl.createDataChannel(WTFMove(label), WTFMove(options), ec));

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

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

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

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

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

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

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

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

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

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

}

#endif // ENABLE(WEB_RTC)
