/*
 * Copyright (c) 2015 Canon Inc.
 * Copyright (c) 2016 Apple Inc. All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 * 
 */

// DO NOT EDIT THIS FILE. It is automatically generated from JavaScript files for
// builtins by the script: Source/JavaScriptCore/Scripts/generate-js-builtins.py

#pragma once

#if ENABLE(MEDIA_STREAM)

#include <builtins/BuiltinUtils.h>
#include <bytecode/UnlinkedFunctionExecutable.h>
#include <runtime/Identifier.h>
#include <runtime/JSFunction.h>

namespace JSC {
class FunctionExecutable;
}

namespace WebCore {

/* NavigatorUserMedia */
extern const char* s_navigatorUserMediaWebkitGetUserMediaCode;
extern const int s_navigatorUserMediaWebkitGetUserMediaCodeLength;
extern const JSC::ConstructAbility s_navigatorUserMediaWebkitGetUserMediaCodeConstructAbility;

#define WEBCORE_FOREACH_NAVIGATORUSERMEDIA_BUILTIN_DATA(macro) \
    macro(webkitGetUserMedia, navigatorUserMediaWebkitGetUserMedia, 3) \

#define WEBCORE_BUILTIN_NAVIGATORUSERMEDIA_WEBKITGETUSERMEDIA 1

#define WEBCORE_FOREACH_NAVIGATORUSERMEDIA_BUILTIN_CODE(macro) \
    macro(navigatorUserMediaWebkitGetUserMediaCode, webkitGetUserMedia, s_navigatorUserMediaWebkitGetUserMediaCodeLength) \

#define WEBCORE_FOREACH_NAVIGATORUSERMEDIA_BUILTIN_FUNCTION_NAME(macro) \
    macro(webkitGetUserMedia) \

#define DECLARE_BUILTIN_GENERATOR(codeName, functionName, argumentCount) \
    JSC::FunctionExecutable* codeName##Generator(JSC::VM&);

WEBCORE_FOREACH_NAVIGATORUSERMEDIA_BUILTIN_CODE(DECLARE_BUILTIN_GENERATOR)
#undef DECLARE_BUILTIN_GENERATOR

class NavigatorUserMediaBuiltinsWrapper : private JSC::WeakHandleOwner {
public:
    explicit NavigatorUserMediaBuiltinsWrapper(JSC::VM* vm)
        : m_vm(*vm)
        WEBCORE_FOREACH_NAVIGATORUSERMEDIA_BUILTIN_FUNCTION_NAME(INITIALIZE_BUILTIN_NAMES)
#define INITIALIZE_BUILTIN_SOURCE_MEMBERS(name, functionName, length) , m_##name##Source(JSC::makeSource(StringImpl::createFromLiteral(s_##name, length)))
        WEBCORE_FOREACH_NAVIGATORUSERMEDIA_BUILTIN_CODE(INITIALIZE_BUILTIN_SOURCE_MEMBERS)
#undef INITIALIZE_BUILTIN_SOURCE_MEMBERS
    {
    }

#define EXPOSE_BUILTIN_EXECUTABLES(name, functionName, length) \
    JSC::UnlinkedFunctionExecutable* name##Executable(); \
    const JSC::SourceCode& name##Source() const { return m_##name##Source; }
    WEBCORE_FOREACH_NAVIGATORUSERMEDIA_BUILTIN_CODE(EXPOSE_BUILTIN_EXECUTABLES)
#undef EXPOSE_BUILTIN_EXECUTABLES

    WEBCORE_FOREACH_NAVIGATORUSERMEDIA_BUILTIN_FUNCTION_NAME(DECLARE_BUILTIN_IDENTIFIER_ACCESSOR)

    void exportNames();

private:
    JSC::VM& m_vm;

    WEBCORE_FOREACH_NAVIGATORUSERMEDIA_BUILTIN_FUNCTION_NAME(DECLARE_BUILTIN_NAMES)

#define DECLARE_BUILTIN_SOURCE_MEMBERS(name, functionName, length) \
    JSC::SourceCode m_##name##Source;\
    JSC::Weak<JSC::UnlinkedFunctionExecutable> m_##name##Executable;
    WEBCORE_FOREACH_NAVIGATORUSERMEDIA_BUILTIN_CODE(DECLARE_BUILTIN_SOURCE_MEMBERS)
#undef DECLARE_BUILTIN_SOURCE_MEMBERS

};

#define DEFINE_BUILTIN_EXECUTABLES(name, functionName, length) \
inline JSC::UnlinkedFunctionExecutable* NavigatorUserMediaBuiltinsWrapper::name##Executable() \
{\
    if (!m_##name##Executable)\
        m_##name##Executable = JSC::Weak<JSC::UnlinkedFunctionExecutable>(JSC::createBuiltinExecutable(m_vm, m_##name##Source, functionName##PublicName(), s_##name##ConstructAbility), this, &m_##name##Executable);\
    return m_##name##Executable.get();\
}
WEBCORE_FOREACH_NAVIGATORUSERMEDIA_BUILTIN_CODE(DEFINE_BUILTIN_EXECUTABLES)
#undef DEFINE_BUILTIN_EXECUTABLES

inline void NavigatorUserMediaBuiltinsWrapper::exportNames()
{
#define EXPORT_FUNCTION_NAME(name) m_vm.propertyNames->appendExternalName(name##PublicName(), name##PrivateName());
    WEBCORE_FOREACH_NAVIGATORUSERMEDIA_BUILTIN_FUNCTION_NAME(EXPORT_FUNCTION_NAME)
#undef EXPORT_FUNCTION_NAME
}

} // namespace WebCore

#endif // ENABLE(MEDIA_STREAM)
