/*
 * Copyright (c) 2015 Canon Inc.
 * Copyright (c) 2015 Igalia S.L.
 * 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(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)

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

namespace JSC {
class FunctionExecutable;
}

namespace WebCore {

/* ByteLengthQueuingStrategy */
extern const char* s_byteLengthQueuingStrategySizeCode;
extern const int s_byteLengthQueuingStrategySizeCodeLength;
extern const JSC::ConstructAbility s_byteLengthQueuingStrategySizeCodeConstructAbility;
extern const char* s_byteLengthQueuingStrategyInitializeByteLengthQueuingStrategyCode;
extern const int s_byteLengthQueuingStrategyInitializeByteLengthQueuingStrategyCodeLength;
extern const JSC::ConstructAbility s_byteLengthQueuingStrategyInitializeByteLengthQueuingStrategyCodeConstructAbility;

#define WEBCORE_FOREACH_BYTELENGTHQUEUINGSTRATEGY_BUILTIN_DATA(macro) \
    macro(size, byteLengthQueuingStrategySize, 1) \
    macro(initializeByteLengthQueuingStrategy, byteLengthQueuingStrategyInitializeByteLengthQueuingStrategy, 1) \

#define WEBCORE_BUILTIN_BYTELENGTHQUEUINGSTRATEGY_SIZE 1
#define WEBCORE_BUILTIN_BYTELENGTHQUEUINGSTRATEGY_INITIALIZEBYTELENGTHQUEUINGSTRATEGY 1

#define WEBCORE_FOREACH_BYTELENGTHQUEUINGSTRATEGY_BUILTIN_CODE(macro) \
    macro(byteLengthQueuingStrategySizeCode, size, s_byteLengthQueuingStrategySizeCodeLength) \
    macro(byteLengthQueuingStrategyInitializeByteLengthQueuingStrategyCode, initializeByteLengthQueuingStrategy, s_byteLengthQueuingStrategyInitializeByteLengthQueuingStrategyCodeLength) \

#define WEBCORE_FOREACH_BYTELENGTHQUEUINGSTRATEGY_BUILTIN_FUNCTION_NAME(macro) \
    macro(initializeByteLengthQueuingStrategy) \
    macro(size) \

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

WEBCORE_FOREACH_BYTELENGTHQUEUINGSTRATEGY_BUILTIN_CODE(DECLARE_BUILTIN_GENERATOR)
#undef DECLARE_BUILTIN_GENERATOR

class ByteLengthQueuingStrategyBuiltinsWrapper : private JSC::WeakHandleOwner {
public:
    explicit ByteLengthQueuingStrategyBuiltinsWrapper(JSC::VM* vm)
        : m_vm(*vm)
        WEBCORE_FOREACH_BYTELENGTHQUEUINGSTRATEGY_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_BYTELENGTHQUEUINGSTRATEGY_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_BYTELENGTHQUEUINGSTRATEGY_BUILTIN_CODE(EXPOSE_BUILTIN_EXECUTABLES)
#undef EXPOSE_BUILTIN_EXECUTABLES

    WEBCORE_FOREACH_BYTELENGTHQUEUINGSTRATEGY_BUILTIN_FUNCTION_NAME(DECLARE_BUILTIN_IDENTIFIER_ACCESSOR)

    void exportNames();

private:
    JSC::VM& m_vm;

    WEBCORE_FOREACH_BYTELENGTHQUEUINGSTRATEGY_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_BYTELENGTHQUEUINGSTRATEGY_BUILTIN_CODE(DECLARE_BUILTIN_SOURCE_MEMBERS)
#undef DECLARE_BUILTIN_SOURCE_MEMBERS

};

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

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

} // namespace WebCore

#endif // ENABLE(READABLE_STREAM_API) || ENABLE(WRITABLE_STREAM_API)
