/*
 * Copyright (c) 2015 Canon Inc. All rights reserved.
 * Copyright (c) 2015 Igalia
 * Copyright (c) 2015 Igalia S.L.
 * Copyright (c) 2015 Igalia.
 * Copyright (c) 2015, 2016 Canon Inc.
 * Copyright (c) 2015, 2016 Ericsson AB. All rights reserved.
 * Copyright (c) 2016 Apple 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

#include "config.h"
#include "WebCoreJSBuiltinInternals.h"

#include "JSDOMGlobalObject.h"
#include "WebCoreJSClientData.h"
#include <heap/HeapInlines.h>
#include <heap/SlotVisitorInlines.h>
#include <runtime/JSCJSValueInlines.h>
#include <runtime/StructureInlines.h>

namespace WebCore {

JSBuiltinInternalFunctions::JSBuiltinInternalFunctions(JSC::VM& vm)
#if ENABLE(WEB_RTC) || ENABLE(FETCH_API) || ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API) || ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
    : m_vm(vm)
#endif // ENABLE(WEB_RTC) || ENABLE(FETCH_API) || ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API) || ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
#if ENABLE(FETCH_API)
    , m_fetchInternals(m_vm)
#endif // ENABLE(FETCH_API)
#if ENABLE(WEB_RTC)
    , m_rtcPeerConnectionInternals(m_vm)
#endif // ENABLE(WEB_RTC)
#if ENABLE(READABLE_STREAM_API)
    , m_readableStreamInternals(m_vm)
#endif // ENABLE(READABLE_STREAM_API)
#if ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
    , m_streamInternals(m_vm)
#endif // ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
#if ENABLE(WRITABLE_STREAM_API)
    , m_writableStreamInternals(m_vm)
#endif // ENABLE(WRITABLE_STREAM_API)
{
    UNUSED_PARAM(vm);
}

void JSBuiltinInternalFunctions::visit(JSC::SlotVisitor& visitor)
{
#if ENABLE(FETCH_API)
    m_fetchInternals.visit(visitor);
#endif // ENABLE(FETCH_API)
#if ENABLE(WEB_RTC)
    m_rtcPeerConnectionInternals.visit(visitor);
#endif // ENABLE(WEB_RTC)
#if ENABLE(READABLE_STREAM_API)
    m_readableStreamInternals.visit(visitor);
#endif // ENABLE(READABLE_STREAM_API)
#if ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
    m_streamInternals.visit(visitor);
#endif // ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
#if ENABLE(WRITABLE_STREAM_API)
    m_writableStreamInternals.visit(visitor);
#endif // ENABLE(WRITABLE_STREAM_API)
    UNUSED_PARAM(visitor);
}

void JSBuiltinInternalFunctions::initialize(JSDOMGlobalObject& globalObject)
{
    UNUSED_PARAM(globalObject);
#if ENABLE(FETCH_API)
    m_fetchInternals.init(globalObject);
#endif // ENABLE(FETCH_API)
#if ENABLE(WEB_RTC)
    m_rtcPeerConnectionInternals.init(globalObject);
#endif // ENABLE(WEB_RTC)
#if ENABLE(READABLE_STREAM_API)
    m_readableStreamInternals.init(globalObject);
#endif // ENABLE(READABLE_STREAM_API)
#if ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
    m_streamInternals.init(globalObject);
#endif // ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
#if ENABLE(WRITABLE_STREAM_API)
    m_writableStreamInternals.init(globalObject);
#endif // ENABLE(WRITABLE_STREAM_API)

#if ENABLE(WEB_RTC) || ENABLE(FETCH_API) || ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API) || ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
    JSVMClientData& clientData = *static_cast<JSVMClientData*>(m_vm.clientData);
    JSDOMGlobalObject::GlobalPropertyInfo staticGlobals[] = {
#if ENABLE(FETCH_API)
#define DECLARE_GLOBAL_STATIC(name) \
    JSDOMGlobalObject::GlobalPropertyInfo( \
        clientData.builtinFunctions().fetchInternalsBuiltins().name##PrivateName(), fetchInternals().m_##name##Function.get() , JSC::DontDelete | JSC::ReadOnly),
    WEBCORE_FOREACH_FETCHINTERNALS_BUILTIN_FUNCTION_NAME(DECLARE_GLOBAL_STATIC)
#undef DECLARE_GLOBAL_STATIC
#endif // ENABLE(FETCH_API)
#if ENABLE(WEB_RTC)
#define DECLARE_GLOBAL_STATIC(name) \
    JSDOMGlobalObject::GlobalPropertyInfo( \
        clientData.builtinFunctions().rtcPeerConnectionInternalsBuiltins().name##PrivateName(), rtcPeerConnectionInternals().m_##name##Function.get() , JSC::DontDelete | JSC::ReadOnly),
    WEBCORE_FOREACH_RTCPEERCONNECTIONINTERNALS_BUILTIN_FUNCTION_NAME(DECLARE_GLOBAL_STATIC)
#undef DECLARE_GLOBAL_STATIC
#endif // ENABLE(WEB_RTC)
#if ENABLE(READABLE_STREAM_API)
#define DECLARE_GLOBAL_STATIC(name) \
    JSDOMGlobalObject::GlobalPropertyInfo( \
        clientData.builtinFunctions().readableStreamInternalsBuiltins().name##PrivateName(), readableStreamInternals().m_##name##Function.get() , JSC::DontDelete | JSC::ReadOnly),
    WEBCORE_FOREACH_READABLESTREAMINTERNALS_BUILTIN_FUNCTION_NAME(DECLARE_GLOBAL_STATIC)
#undef DECLARE_GLOBAL_STATIC
#endif // ENABLE(READABLE_STREAM_API)
#if ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
#define DECLARE_GLOBAL_STATIC(name) \
    JSDOMGlobalObject::GlobalPropertyInfo( \
        clientData.builtinFunctions().streamInternalsBuiltins().name##PrivateName(), streamInternals().m_##name##Function.get() , JSC::DontDelete | JSC::ReadOnly),
    WEBCORE_FOREACH_STREAMINTERNALS_BUILTIN_FUNCTION_NAME(DECLARE_GLOBAL_STATIC)
#undef DECLARE_GLOBAL_STATIC
#endif // ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
#if ENABLE(WRITABLE_STREAM_API)
#define DECLARE_GLOBAL_STATIC(name) \
    JSDOMGlobalObject::GlobalPropertyInfo( \
        clientData.builtinFunctions().writableStreamInternalsBuiltins().name##PrivateName(), writableStreamInternals().m_##name##Function.get() , JSC::DontDelete | JSC::ReadOnly),
    WEBCORE_FOREACH_WRITABLESTREAMINTERNALS_BUILTIN_FUNCTION_NAME(DECLARE_GLOBAL_STATIC)
#undef DECLARE_GLOBAL_STATIC
#endif // ENABLE(WRITABLE_STREAM_API)
    };
    globalObject.addStaticGlobals(staticGlobals, WTF_ARRAY_LENGTH(staticGlobals));
    UNUSED_PARAM(clientData);
#endif // ENABLE(WEB_RTC) || ENABLE(FETCH_API) || ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API) || ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
}

} // namespace WebCore
