/*
    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_AUDIO)

#include "JSAudioContext.h"

#include "AnalyserNode.h"
#include "AudioBuffer.h"
#include "AudioBufferSourceNode.h"
#include "BiquadFilterNode.h"
#include "ChannelMergerNode.h"
#include "ChannelSplitterNode.h"
#include "ConvolverNode.h"
#include "DelayNode.h"
#include "Document.h"
#include "DynamicsCompressorNode.h"
#include "EventNames.h"
#include "ExceptionCode.h"
#include "GainNode.h"
#include "JSAnalyserNode.h"
#include "JSAudioBuffer.h"
#include "JSAudioBufferCallback.h"
#include "JSAudioBufferSourceNode.h"
#include "JSAudioDestinationNode.h"
#include "JSAudioListener.h"
#include "JSBiquadFilterNode.h"
#include "JSChannelMergerNode.h"
#include "JSChannelSplitterNode.h"
#include "JSConvolverNode.h"
#include "JSDOMBinding.h"
#include "JSDOMConstructor.h"
#include "JSDOMConvert.h"
#include "JSDOMPromise.h"
#include "JSDelayNode.h"
#include "JSDynamicsCompressorNode.h"
#include "JSEventListener.h"
#include "JSGainNode.h"
#include "JSOscillatorNode.h"
#include "JSPannerNode.h"
#include "JSPeriodicWave.h"
#include "JSScriptProcessorNode.h"
#include "JSWaveShaperNode.h"
#include "MediaElementAudioSourceNode.h"
#include "MediaStreamAudioDestinationNode.h"
#include "MediaStreamAudioSourceNode.h"
#include "OscillatorNode.h"
#include "PannerNode.h"
#include "PeriodicWave.h"
#include "ScriptProcessorNode.h"
#include "WaveShaperNode.h"
#include <runtime/Error.h>
#include <runtime/JSString.h>
#include <wtf/GetPtr.h>

#if ENABLE(MEDIA_STREAM)
#include "JSMediaStream.h"
#include "JSMediaStreamAudioDestinationNode.h"
#include "JSMediaStreamAudioSourceNode.h"
#endif

#if ENABLE(VIDEO)
#include "JSHTMLMediaElement.h"
#include "JSMediaElementAudioSourceNode.h"
#endif

using namespace JSC;

namespace WebCore {

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

JSString* jsStringWithCache(ExecState*, AudioContext::State);

JSString* jsStringWithCache(ExecState* state, AudioContext::State enumerationValue)
{
    static NeverDestroyed<const String> values[] = {
        ASCIILiteral("suspended"),
        ASCIILiteral("running"),
        ASCIILiteral("interrupted"),
        ASCIILiteral("closed"),
    };
    static_assert(static_cast<size_t>(AudioContext::State::Suspended) == 0, "AudioContext::State::Suspended is not 0 as expected");
    static_assert(static_cast<size_t>(AudioContext::State::Running) == 1, "AudioContext::State::Running is not 1 as expected");
    static_assert(static_cast<size_t>(AudioContext::State::Interrupted) == 2, "AudioContext::State::Interrupted is not 2 as expected");
    static_assert(static_cast<size_t>(AudioContext::State::Closed) == 3, "AudioContext::State::Closed 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<AudioContext::State> {
    static JSString* arrayJSValue(ExecState* state, JSDOMGlobalObject*, AudioContext::State value) { return jsStringWithCache(state, value); }
};

template<> Optional<AudioContext::State> parse<AudioContext::State>(ExecState& state, JSValue value)
{
    auto stringValue = value.toWTFString(&state);
    if (stringValue == "suspended")
        return AudioContext::State::Suspended;
    if (stringValue == "running")
        return AudioContext::State::Running;
    if (stringValue == "interrupted")
        return AudioContext::State::Interrupted;
    if (stringValue == "closed")
        return AudioContext::State::Closed;
    return Nullopt;
}

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

template<> inline const char* expectedEnumerationValues<AudioContext::State>()
{
    return "\"suspended\", \"running\", \"interrupted\", \"closed\"";
}

// Functions

JSC::EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionSuspend(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionResume(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionClose(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionCreateBuffer(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionDecodeAudioData(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionCreateBufferSource(JSC::ExecState*);
#if ENABLE(VIDEO)
JSC::EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionCreateMediaElementSource(JSC::ExecState*);
#endif
#if ENABLE(MEDIA_STREAM)
JSC::EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionCreateMediaStreamSource(JSC::ExecState*);
#endif
#if ENABLE(MEDIA_STREAM)
JSC::EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionCreateMediaStreamDestination(JSC::ExecState*);
#endif
JSC::EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionCreateGain(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionCreateDelay(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionCreateBiquadFilter(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionCreateWaveShaper(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionCreatePanner(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionCreateConvolver(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionCreateDynamicsCompressor(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionCreateAnalyser(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionCreateScriptProcessor(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionCreateOscillator(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionCreatePeriodicWave(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionCreateChannelSplitter(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionCreateChannelMerger(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionStartRendering(JSC::ExecState*);

// Attributes

JSC::EncodedJSValue jsAudioContextDestination(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsAudioContextCurrentTime(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsAudioContextSampleRate(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsAudioContextListener(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsAudioContextState(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsAudioContextOnstatechange(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSAudioContextOnstatechange(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsAudioContextActiveSourceCount(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsAudioContextOncomplete(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSAudioContextOncomplete(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsAudioContextConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSAudioContextConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);

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

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

typedef JSDOMConstructor<JSAudioContext> JSAudioContextConstructor;

template<> EncodedJSValue JSC_HOST_CALL JSAudioContextConstructor::construct(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    auto* castedThis = jsCast<JSAudioContextConstructor*>(state->callee());
    ASSERT(castedThis);
    ScriptExecutionContext* context = castedThis->scriptExecutionContext();
    if (UNLIKELY(!context))
        return throwConstructorScriptExecutionContextUnavailableError(*state, throwScope, "webkitAudioContext");
    ASSERT(context->isDocument());
    auto& document = downcast<Document>(*context);
    auto object = AudioContext::create(document);
    return JSValue::encode(toJSNewlyCreated(state, castedThis->globalObject(), WTFMove(object)));
}

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

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

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

/* Hash table for prototype */

static const HashTableValue JSAudioContextPrototypeTableValues[] =
{
    { "constructor", DontEnum, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsAudioContextConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSAudioContextConstructor) } },
    { "destination", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsAudioContextDestination), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "currentTime", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsAudioContextCurrentTime), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "sampleRate", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsAudioContextSampleRate), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "listener", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsAudioContextListener), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "state", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsAudioContextState), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "onstatechange", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsAudioContextOnstatechange), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSAudioContextOnstatechange) } },
    { "activeSourceCount", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsAudioContextActiveSourceCount), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "oncomplete", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsAudioContextOncomplete), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSAudioContextOncomplete) } },
    { "suspend", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsAudioContextPrototypeFunctionSuspend), (intptr_t) (0) } },
    { "resume", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsAudioContextPrototypeFunctionResume), (intptr_t) (0) } },
    { "close", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsAudioContextPrototypeFunctionClose), (intptr_t) (0) } },
    { "createBuffer", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsAudioContextPrototypeFunctionCreateBuffer), (intptr_t) (2) } },
    { "decodeAudioData", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsAudioContextPrototypeFunctionDecodeAudioData), (intptr_t) (2) } },
    { "createBufferSource", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsAudioContextPrototypeFunctionCreateBufferSource), (intptr_t) (0) } },
#if ENABLE(VIDEO)
    { "createMediaElementSource", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsAudioContextPrototypeFunctionCreateMediaElementSource), (intptr_t) (1) } },
#else
    { 0, 0, NoIntrinsic, { 0, 0 } },
#endif
#if ENABLE(MEDIA_STREAM)
    { "createMediaStreamSource", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsAudioContextPrototypeFunctionCreateMediaStreamSource), (intptr_t) (1) } },
#else
    { 0, 0, NoIntrinsic, { 0, 0 } },
#endif
#if ENABLE(MEDIA_STREAM)
    { "createMediaStreamDestination", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsAudioContextPrototypeFunctionCreateMediaStreamDestination), (intptr_t) (0) } },
#else
    { 0, 0, NoIntrinsic, { 0, 0 } },
#endif
    { "createGain", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsAudioContextPrototypeFunctionCreateGain), (intptr_t) (0) } },
    { "createDelay", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsAudioContextPrototypeFunctionCreateDelay), (intptr_t) (0) } },
    { "createBiquadFilter", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsAudioContextPrototypeFunctionCreateBiquadFilter), (intptr_t) (0) } },
    { "createWaveShaper", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsAudioContextPrototypeFunctionCreateWaveShaper), (intptr_t) (0) } },
    { "createPanner", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsAudioContextPrototypeFunctionCreatePanner), (intptr_t) (0) } },
    { "createConvolver", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsAudioContextPrototypeFunctionCreateConvolver), (intptr_t) (0) } },
    { "createDynamicsCompressor", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsAudioContextPrototypeFunctionCreateDynamicsCompressor), (intptr_t) (0) } },
    { "createAnalyser", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsAudioContextPrototypeFunctionCreateAnalyser), (intptr_t) (0) } },
    { "createScriptProcessor", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsAudioContextPrototypeFunctionCreateScriptProcessor), (intptr_t) (1) } },
    { "createOscillator", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsAudioContextPrototypeFunctionCreateOscillator), (intptr_t) (0) } },
    { "createPeriodicWave", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsAudioContextPrototypeFunctionCreatePeriodicWave), (intptr_t) (2) } },
    { "createChannelSplitter", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsAudioContextPrototypeFunctionCreateChannelSplitter), (intptr_t) (0) } },
    { "createChannelMerger", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsAudioContextPrototypeFunctionCreateChannelMerger), (intptr_t) (0) } },
    { "startRendering", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsAudioContextPrototypeFunctionStartRendering), (intptr_t) (0) } },
};

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

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

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

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

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

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

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


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


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


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


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


EncodedJSValue jsAudioContextOnstatechange(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<JSAudioContext*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "webkitAudioContext", "onstatechange");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().statechangeEvent));
}


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


EncodedJSValue jsAudioContextOncomplete(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<JSAudioContext*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "webkitAudioContext", "oncomplete");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().completeEvent));
}


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

bool setJSAudioContextConstructor(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    JSValue value = JSValue::decode(encodedValue);
    JSAudioContextPrototype* domObject = jsDynamicCast<JSAudioContextPrototype*>(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 setJSAudioContextOnstatechange(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);
    JSAudioContext* castedThis = jsDynamicCast<JSAudioContext*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "webkitAudioContext", "onstatechange");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().statechangeEvent, value);
    return true;
}


bool setJSAudioContextOncomplete(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);
    JSAudioContext* castedThis = jsDynamicCast<JSAudioContext*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "webkitAudioContext", "oncomplete");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().completeEvent, value);
    return true;
}


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

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

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

static inline EncodedJSValue jsAudioContextPrototypeFunctionSuspendPromise(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<JSAudioContext*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitAudioContext", "suspend");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSAudioContext::info());
    auto& impl = castedThis->wrapped();
    impl.suspend(WTFMove(promise));
    return JSValue::encode(jsUndefined());
}

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

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

static inline EncodedJSValue jsAudioContextPrototypeFunctionResumePromise(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<JSAudioContext*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitAudioContext", "resume");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSAudioContext::info());
    auto& impl = castedThis->wrapped();
    impl.resume(WTFMove(promise));
    return JSValue::encode(jsUndefined());
}

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

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

static inline EncodedJSValue jsAudioContextPrototypeFunctionClosePromise(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<JSAudioContext*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitAudioContext", "close");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSAudioContext::info());
    auto& impl = castedThis->wrapped();
    impl.close(WTFMove(promise));
    return JSValue::encode(jsUndefined());
}

static inline EncodedJSValue jsAudioContextPrototypeFunctionCreateBuffer1(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSAudioContext*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitAudioContext", "createBuffer");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSAudioContext::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 3))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto numberOfChannels = convert<uint32_t>(*state, state->uncheckedArgument(0), NormalConversion);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    auto numberOfFrames = convert<uint32_t>(*state, state->uncheckedArgument(1), NormalConversion);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    auto sampleRate = convert<float>(*state, state->uncheckedArgument(2), ShouldAllowNonFinite::Yes);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    JSValue result = toJS(state, castedThis->globalObject(), impl.createBuffer(WTFMove(numberOfChannels), WTFMove(numberOfFrames), WTFMove(sampleRate), ec));

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

static inline EncodedJSValue jsAudioContextPrototypeFunctionCreateBuffer2(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSAudioContext*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitAudioContext", "createBuffer");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSAudioContext::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 2))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto buffer = toArrayBuffer(state->uncheckedArgument(0));
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    if (UNLIKELY(!buffer))
        return throwArgumentTypeError(*state, throwScope, 0, "buffer", "webkitAudioContext", "createBuffer", "ArrayBuffer");
    auto mixToMono = state->uncheckedArgument(1).toBoolean(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    JSValue result = toJS(state, castedThis->globalObject(), impl.createBuffer(*buffer, WTFMove(mixToMono), ec));

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

EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionCreateBuffer(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    size_t argsCount = std::min<size_t>(3, state->argumentCount());
    if (argsCount == 2) {
        return jsAudioContextPrototypeFunctionCreateBuffer2(state);
    }
    if (argsCount == 3) {
        return jsAudioContextPrototypeFunctionCreateBuffer1(state);
    }
    return argsCount < 2 ? throwVMError(state, throwScope, createNotEnoughArgumentsError(state)) : throwVMTypeError(state, throwScope);
}

EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionDecodeAudioData(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSAudioContext*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitAudioContext", "decodeAudioData");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSAudioContext::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 2))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    auto audioData = toArrayBuffer(state->uncheckedArgument(0));
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    if (UNLIKELY(!audioData))
        return throwArgumentTypeError(*state, throwScope, 0, "audioData", "webkitAudioContext", "decodeAudioData", "ArrayBuffer");
    if (UNLIKELY(!state->uncheckedArgument(1).isFunction()))
        return throwArgumentMustBeFunctionError(*state, throwScope, 1, "successCallback", "webkitAudioContext", "decodeAudioData");
    auto successCallback = JSAudioBufferCallback::create(asObject(state->uncheckedArgument(1)), castedThis->globalObject());
    RefPtr<AudioBufferCallback> errorCallback;
    if (!state->argument(2).isUndefinedOrNull()) {
        if (!state->uncheckedArgument(2).isFunction())
            return throwArgumentMustBeFunctionError(*state, throwScope, 2, "errorCallback", "webkitAudioContext", "decodeAudioData");
        errorCallback = JSAudioBufferCallback::create(asObject(state->uncheckedArgument(2)), castedThis->globalObject());
    }
    impl.decodeAudioData(*audioData, WTFMove(successCallback), WTFMove(errorCallback));
    return JSValue::encode(jsUndefined());
}

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

#if ENABLE(VIDEO)
EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionCreateMediaElementSource(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSAudioContext*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitAudioContext", "createMediaElementSource");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSAudioContext::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto mediaElement = JSHTMLMediaElement::toWrapped(state->uncheckedArgument(0));
    if (UNLIKELY(!mediaElement))
        return throwArgumentTypeError(*state, throwScope, 0, "mediaElement", "webkitAudioContext", "createMediaElementSource", "HTMLMediaElement");
    JSValue result = toJS(state, castedThis->globalObject(), impl.createMediaElementSource(*mediaElement, ec));

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

#endif

#if ENABLE(MEDIA_STREAM)
EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionCreateMediaStreamSource(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSAudioContext*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitAudioContext", "createMediaStreamSource");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSAudioContext::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto mediaStream = JSMediaStream::toWrapped(state->uncheckedArgument(0));
    if (UNLIKELY(!mediaStream))
        return throwArgumentTypeError(*state, throwScope, 0, "mediaStream", "webkitAudioContext", "createMediaStreamSource", "MediaStream");
    JSValue result = toJS(state, castedThis->globalObject(), impl.createMediaStreamSource(*mediaStream, ec));

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

#endif

#if ENABLE(MEDIA_STREAM)
EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionCreateMediaStreamDestination(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSAudioContext*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitAudioContext", "createMediaStreamDestination");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSAudioContext::info());
    auto& impl = castedThis->wrapped();
    JSValue result = toJS(state, castedThis->globalObject(), impl.createMediaStreamDestination());
    return JSValue::encode(result);
}

#endif

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

EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionCreateDelay(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSAudioContext*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitAudioContext", "createDelay");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSAudioContext::info());
    auto& impl = castedThis->wrapped();
    ExceptionCode ec = 0;
    auto maxDelayTime = state->argument(0).isUndefined() ? 1 : convert<double>(*state, state->uncheckedArgument(0), ShouldAllowNonFinite::Yes);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    JSValue result = toJS(state, castedThis->globalObject(), impl.createDelay(WTFMove(maxDelayTime), ec));

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

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

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

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

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

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

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

EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionCreateScriptProcessor(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSAudioContext*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitAudioContext", "createScriptProcessor");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSAudioContext::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto bufferSize = convert<uint32_t>(*state, state->uncheckedArgument(0), NormalConversion);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    auto numberOfInputChannels = state->argument(1).isUndefined() ? 2 : convert<uint32_t>(*state, state->uncheckedArgument(1), NormalConversion);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    auto numberOfOutputChannels = state->argument(2).isUndefined() ? 2 : convert<uint32_t>(*state, state->uncheckedArgument(2), NormalConversion);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    JSValue result = toJS(state, castedThis->globalObject(), impl.createScriptProcessor(WTFMove(bufferSize), WTFMove(numberOfInputChannels), WTFMove(numberOfOutputChannels), ec));

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

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

EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionCreatePeriodicWave(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSAudioContext*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitAudioContext", "createPeriodicWave");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSAudioContext::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 2))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto real = toFloat32Array(state->uncheckedArgument(0));
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    if (UNLIKELY(!real))
        return throwArgumentTypeError(*state, throwScope, 0, "real", "webkitAudioContext", "createPeriodicWave", "Float32Array");
    auto imag = toFloat32Array(state->uncheckedArgument(1));
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    if (UNLIKELY(!imag))
        return throwArgumentTypeError(*state, throwScope, 1, "imag", "webkitAudioContext", "createPeriodicWave", "Float32Array");
    JSValue result = toJS(state, castedThis->globalObject(), impl.createPeriodicWave(real.releaseNonNull(), imag.releaseNonNull(), ec));

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

EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionCreateChannelSplitter(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSAudioContext*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitAudioContext", "createChannelSplitter");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSAudioContext::info());
    auto& impl = castedThis->wrapped();
    ExceptionCode ec = 0;
    auto numberOfOutputs = state->argument(0).isUndefined() ? 6 : convert<uint32_t>(*state, state->uncheckedArgument(0), NormalConversion);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    JSValue result = toJS(state, castedThis->globalObject(), impl.createChannelSplitter(WTFMove(numberOfOutputs), ec));

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

EncodedJSValue JSC_HOST_CALL jsAudioContextPrototypeFunctionCreateChannelMerger(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSAudioContext*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "webkitAudioContext", "createChannelMerger");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSAudioContext::info());
    auto& impl = castedThis->wrapped();
    ExceptionCode ec = 0;
    auto numberOfInputs = state->argument(0).isUndefined() ? 6 : convert<uint32_t>(*state, state->uncheckedArgument(0), NormalConversion);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    JSValue result = toJS(state, castedThis->globalObject(), impl.createChannelMerger(WTFMove(numberOfInputs), ec));

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

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

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

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

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

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

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

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

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

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

}

#endif // ENABLE(WEB_AUDIO)
