### Begin File: WebCoreJSBuiltins.h
/*
 * Copyright (c) 2015 Canon Inc. All rights reserved.
 * 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

#include "AnotherGuardedInternalBuiltinBuiltins.h"
#include "ArbitraryConditionalGuardBuiltins.h"
#include "GuardedBuiltinBuiltins.h"
#include "GuardedInternalBuiltinBuiltins.h"
#include "UnguardedBuiltinBuiltins.h"
#include "xmlCasingTestBuiltins.h"
#include <JavaScriptCore/VM.h>

namespace WebCore {

class JSBuiltinFunctions {
public:
    explicit JSBuiltinFunctions(JSC::VM& vm)
        : m_vm(vm)
#if ENABLE(FETCH_API)
        , m_anotherGuardedInternalBuiltinBuiltins(m_vm)
#endif // ENABLE(FETCH_API)
#if ENABLE(STREAMS_API) || USE(CF)
        , m_arbitraryConditionalGuardBuiltins(m_vm)
#endif // ENABLE(STREAMS_API) || USE(CF)
#if ENABLE(STREAMS_API)
        , m_guardedBuiltinBuiltins(m_vm)
#endif // ENABLE(STREAMS_API)
#if ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
        , m_guardedInternalBuiltinBuiltins(m_vm)
#endif // ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
        , m_unguardedBuiltinBuiltins(m_vm)
#if ENABLE(STREAMS_API)
        , m_xmlCasingTestBuiltins(m_vm)
#endif // ENABLE(STREAMS_API)
    {
#if ENABLE(FETCH_API)
        m_anotherGuardedInternalBuiltinBuiltins.exportNames();
#endif // ENABLE(FETCH_API)
#if ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
        m_guardedInternalBuiltinBuiltins.exportNames();
#endif // ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
#if ENABLE(STREAMS_API)
        m_xmlCasingTestBuiltins.exportNames();
#endif // ENABLE(STREAMS_API)
    }

#if ENABLE(FETCH_API)
    AnotherGuardedInternalBuiltinBuiltinsWrapper& anotherGuardedInternalBuiltinBuiltins() { return m_anotherGuardedInternalBuiltinBuiltins; }
#endif // ENABLE(FETCH_API)
#if ENABLE(STREAMS_API) || USE(CF)
    ArbitraryConditionalGuardBuiltinsWrapper& arbitraryConditionalGuardBuiltins() { return m_arbitraryConditionalGuardBuiltins; }
#endif // ENABLE(STREAMS_API) || USE(CF)
#if ENABLE(STREAMS_API)
    GuardedBuiltinBuiltinsWrapper& guardedBuiltinBuiltins() { return m_guardedBuiltinBuiltins; }
#endif // ENABLE(STREAMS_API)
#if ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
    GuardedInternalBuiltinBuiltinsWrapper& guardedInternalBuiltinBuiltins() { return m_guardedInternalBuiltinBuiltins; }
#endif // ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
    UnguardedBuiltinBuiltinsWrapper& unguardedBuiltinBuiltins() { return m_unguardedBuiltinBuiltins; }
#if ENABLE(STREAMS_API)
    XMLCasingTestBuiltinsWrapper& xmlCasingTestBuiltins() { return m_xmlCasingTestBuiltins; }
#endif // ENABLE(STREAMS_API)

private:
    JSC::VM& m_vm;
#if ENABLE(FETCH_API)
    AnotherGuardedInternalBuiltinBuiltinsWrapper m_anotherGuardedInternalBuiltinBuiltins;
#endif // ENABLE(FETCH_API)
#if ENABLE(STREAMS_API) || USE(CF)
    ArbitraryConditionalGuardBuiltinsWrapper m_arbitraryConditionalGuardBuiltins;
#endif // ENABLE(STREAMS_API) || USE(CF)
#if ENABLE(STREAMS_API)
    GuardedBuiltinBuiltinsWrapper m_guardedBuiltinBuiltins;
#endif // ENABLE(STREAMS_API)
#if ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
    GuardedInternalBuiltinBuiltinsWrapper m_guardedInternalBuiltinBuiltins;
#endif // ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
    UnguardedBuiltinBuiltinsWrapper m_unguardedBuiltinBuiltins;
#if ENABLE(STREAMS_API)
    XMLCasingTestBuiltinsWrapper m_xmlCasingTestBuiltins;
#endif // ENABLE(STREAMS_API)
};

} // namespace WebCore
### End File: WebCoreJSBuiltins.h

### Begin File: WebCoreJSBuiltins.cpp
/*
 * Copyright (c) 2015 Canon Inc. All rights reserved.
 * 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 "AnotherGuardedInternalBuiltinBuiltins.cpp"
#include "ArbitraryConditionalGuardBuiltins.cpp"
#include "GuardedBuiltinBuiltins.cpp"
#include "GuardedInternalBuiltinBuiltins.cpp"
#include "UnguardedBuiltinBuiltins.cpp"
#include "xmlCasingTestBuiltins.cpp"
### End File: WebCoreJSBuiltins.cpp

### Begin File: WebCoreJSBuiltinInternals.h
/*
 * Copyright (c) 2015 Canon Inc. All rights reserved.
 * 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

#include "AnotherGuardedInternalBuiltinBuiltins.h"
#include "GuardedInternalBuiltinBuiltins.h"
#include "xmlCasingTestBuiltins.h"
#include <JavaScriptCore/VM.h>
#include <JavaScriptCore/WeakInlines.h>

namespace WebCore {

class JSDOMGlobalObject;

class JSBuiltinInternalFunctions {
public:
    explicit JSBuiltinInternalFunctions(JSC::VM&);

    void visit(JSC::SlotVisitor&);
    void initialize(JSDOMGlobalObject&);

#if ENABLE(FETCH_API)
    AnotherGuardedInternalBuiltinBuiltinFunctions& anotherGuardedInternalBuiltin() { return m_anotherGuardedInternalBuiltin; }
#endif // ENABLE(FETCH_API)
#if ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
    GuardedInternalBuiltinBuiltinFunctions& guardedInternalBuiltin() { return m_guardedInternalBuiltin; }
#endif // ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
#if ENABLE(STREAMS_API)
    XMLCasingTestBuiltinFunctions& xmlCasingTest() { return m_xmlCasingTest; }
#endif // ENABLE(STREAMS_API)

private:
    JSC::VM& m_vm;
#if ENABLE(FETCH_API)
    AnotherGuardedInternalBuiltinBuiltinFunctions m_anotherGuardedInternalBuiltin;
#endif // ENABLE(FETCH_API)
#if ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
    GuardedInternalBuiltinBuiltinFunctions m_guardedInternalBuiltin;
#endif // ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
#if ENABLE(STREAMS_API)
    XMLCasingTestBuiltinFunctions m_xmlCasingTest;
#endif // ENABLE(STREAMS_API)
};

} // namespace WebCore
### End File: WebCoreJSBuiltinInternals.h

### Begin File: WebCoreJSBuiltinInternals.cpp
/*
 * Copyright (c) 2015 Canon Inc. All rights reserved.
 * 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 <JavaScriptCore/HeapInlines.h>
#include <JavaScriptCore/JSCJSValueInlines.h>
#include <JavaScriptCore/SlotVisitorInlines.h>
#include <JavaScriptCore/StructureInlines.h>

namespace WebCore {

JSBuiltinInternalFunctions::JSBuiltinInternalFunctions(JSC::VM& vm)
    : m_vm(vm)
#if ENABLE(FETCH_API)
    , m_anotherGuardedInternalBuiltin(m_vm)
#endif // ENABLE(FETCH_API)
#if ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
    , m_guardedInternalBuiltin(m_vm)
#endif // ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
#if ENABLE(STREAMS_API)
    , m_xmlCasingTest(m_vm)
#endif // ENABLE(STREAMS_API)
{
    UNUSED_PARAM(vm);
}

void JSBuiltinInternalFunctions::visit(JSC::SlotVisitor& visitor)
{
#if ENABLE(FETCH_API)
    m_anotherGuardedInternalBuiltin.visit(visitor);
#endif // ENABLE(FETCH_API)
#if ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
    m_guardedInternalBuiltin.visit(visitor);
#endif // ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
#if ENABLE(STREAMS_API)
    m_xmlCasingTest.visit(visitor);
#endif // ENABLE(STREAMS_API)
    UNUSED_PARAM(visitor);
}

void JSBuiltinInternalFunctions::initialize(JSDOMGlobalObject& globalObject)
{
    UNUSED_PARAM(globalObject);
#if ENABLE(FETCH_API)
    m_anotherGuardedInternalBuiltin.init(globalObject);
#endif // ENABLE(FETCH_API)
#if ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
    m_guardedInternalBuiltin.init(globalObject);
#endif // ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
#if ENABLE(STREAMS_API)
    m_xmlCasingTest.init(globalObject);
#endif // ENABLE(STREAMS_API)

#if ENABLE(FETCH_API) || ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API) || ENABLE(STREAMS_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().anotherGuardedInternalBuiltinBuiltins().name##PrivateName(), anotherGuardedInternalBuiltin().m_##name##Function.get() , JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly),
    WEBCORE_FOREACH_ANOTHERGUARDEDINTERNALBUILTIN_BUILTIN_FUNCTION_NAME(DECLARE_GLOBAL_STATIC)
#undef DECLARE_GLOBAL_STATIC
#endif // ENABLE(FETCH_API)
#if ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
#define DECLARE_GLOBAL_STATIC(name) \
    JSDOMGlobalObject::GlobalPropertyInfo( \
        clientData.builtinFunctions().guardedInternalBuiltinBuiltins().name##PrivateName(), guardedInternalBuiltin().m_##name##Function.get() , JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly),
    WEBCORE_FOREACH_GUARDEDINTERNALBUILTIN_BUILTIN_FUNCTION_NAME(DECLARE_GLOBAL_STATIC)
#undef DECLARE_GLOBAL_STATIC
#endif // ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
#if ENABLE(STREAMS_API)
#define DECLARE_GLOBAL_STATIC(name) \
    JSDOMGlobalObject::GlobalPropertyInfo( \
        clientData.builtinFunctions().xmlCasingTestBuiltins().name##PrivateName(), xmlCasingTest().m_##name##Function.get() , JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly),
    WEBCORE_FOREACH_XMLCASINGTEST_BUILTIN_FUNCTION_NAME(DECLARE_GLOBAL_STATIC)
#undef DECLARE_GLOBAL_STATIC
#endif // ENABLE(STREAMS_API)
    };
    globalObject.addStaticGlobals(staticGlobals, WTF_ARRAY_LENGTH(staticGlobals));
    UNUSED_PARAM(clientData);
#endif // ENABLE(FETCH_API) || ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API) || ENABLE(STREAMS_API)
}

} // namespace WebCore
### End File: WebCoreJSBuiltinInternals.cpp
