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

#pragma once

#if ENABLE(FETCH_API)

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

namespace JSC {
class FunctionExecutable;
}

namespace WebCore {

/* FetchInternals */
extern const char* s_fetchInternalsFillFetchHeadersCode;
extern const int s_fetchInternalsFillFetchHeadersCodeLength;
extern const JSC::ConstructAbility s_fetchInternalsFillFetchHeadersCodeConstructAbility;
extern const char* s_fetchInternalsConsumeStreamCode;
extern const int s_fetchInternalsConsumeStreamCodeLength;
extern const JSC::ConstructAbility s_fetchInternalsConsumeStreamCodeConstructAbility;

#define WEBCORE_FOREACH_FETCHINTERNALS_BUILTIN_DATA(macro) \
    macro(fillFetchHeaders, fetchInternalsFillFetchHeaders, 2) \
    macro(consumeStream, fetchInternalsConsumeStream, 2) \

#define WEBCORE_BUILTIN_FETCHINTERNALS_FILLFETCHHEADERS 1
#define WEBCORE_BUILTIN_FETCHINTERNALS_CONSUMESTREAM 1

#define WEBCORE_FOREACH_FETCHINTERNALS_BUILTIN_CODE(macro) \
    macro(fetchInternalsFillFetchHeadersCode, fillFetchHeaders, s_fetchInternalsFillFetchHeadersCodeLength) \
    macro(fetchInternalsConsumeStreamCode, consumeStream, s_fetchInternalsConsumeStreamCodeLength) \

#define WEBCORE_FOREACH_FETCHINTERNALS_BUILTIN_FUNCTION_NAME(macro) \
    macro(consumeStream) \
    macro(fillFetchHeaders) \

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

WEBCORE_FOREACH_FETCHINTERNALS_BUILTIN_CODE(DECLARE_BUILTIN_GENERATOR)
#undef DECLARE_BUILTIN_GENERATOR

class FetchInternalsBuiltinsWrapper : private JSC::WeakHandleOwner {
public:
    explicit FetchInternalsBuiltinsWrapper(JSC::VM* vm)
        : m_vm(*vm)
        WEBCORE_FOREACH_FETCHINTERNALS_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_FETCHINTERNALS_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_FETCHINTERNALS_BUILTIN_CODE(EXPOSE_BUILTIN_EXECUTABLES)
#undef EXPOSE_BUILTIN_EXECUTABLES

    WEBCORE_FOREACH_FETCHINTERNALS_BUILTIN_FUNCTION_NAME(DECLARE_BUILTIN_IDENTIFIER_ACCESSOR)

    void exportNames();

private:
    JSC::VM& m_vm;

    WEBCORE_FOREACH_FETCHINTERNALS_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_FETCHINTERNALS_BUILTIN_CODE(DECLARE_BUILTIN_SOURCE_MEMBERS)
#undef DECLARE_BUILTIN_SOURCE_MEMBERS

};

#define DEFINE_BUILTIN_EXECUTABLES(name, functionName, length) \
inline JSC::UnlinkedFunctionExecutable* FetchInternalsBuiltinsWrapper::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_FETCHINTERNALS_BUILTIN_CODE(DEFINE_BUILTIN_EXECUTABLES)
#undef DEFINE_BUILTIN_EXECUTABLES

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

class FetchInternalsBuiltinFunctions {
public:
    explicit FetchInternalsBuiltinFunctions(JSC::VM& vm) : m_vm(vm) { }

    void init(JSC::JSGlobalObject&);
    void visit(JSC::SlotVisitor&);

public:
    JSC::VM& m_vm;

#define DECLARE_BUILTIN_SOURCE_MEMBERS(functionName) \
    JSC::WriteBarrier<JSC::JSFunction> m_##functionName##Function;
    WEBCORE_FOREACH_FETCHINTERNALS_BUILTIN_FUNCTION_NAME(DECLARE_BUILTIN_SOURCE_MEMBERS)
#undef DECLARE_BUILTIN_SOURCE_MEMBERS
};

inline void FetchInternalsBuiltinFunctions::init(JSC::JSGlobalObject& globalObject)
{
#define EXPORT_FUNCTION(codeName, functionName, length)\
    m_##functionName##Function.set(m_vm, &globalObject, JSC::JSFunction::createBuiltinFunction(m_vm, codeName##Generator(m_vm), &globalObject));
    WEBCORE_FOREACH_FETCHINTERNALS_BUILTIN_CODE(EXPORT_FUNCTION)
#undef EXPORT_FUNCTION
}

inline void FetchInternalsBuiltinFunctions::visit(JSC::SlotVisitor& visitor)
{
#define VISIT_FUNCTION(name) visitor.append(&m_##name##Function);
    WEBCORE_FOREACH_FETCHINTERNALS_BUILTIN_FUNCTION_NAME(VISIT_FUNCTION)
#undef VISIT_FUNCTION
}


} // namespace WebCore

#endif // ENABLE(FETCH_API)
