/*
 * 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(READABLE_STREAM_API)

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

namespace JSC {
class FunctionExecutable;
}

namespace WebCore {

/* ReadableStreamDefaultReader */
extern const char* s_readableStreamDefaultReaderCancelCode;
extern const int s_readableStreamDefaultReaderCancelCodeLength;
extern const JSC::ConstructAbility s_readableStreamDefaultReaderCancelCodeConstructAbility;
extern const char* s_readableStreamDefaultReaderReadCode;
extern const int s_readableStreamDefaultReaderReadCodeLength;
extern const JSC::ConstructAbility s_readableStreamDefaultReaderReadCodeConstructAbility;
extern const char* s_readableStreamDefaultReaderReleaseLockCode;
extern const int s_readableStreamDefaultReaderReleaseLockCodeLength;
extern const JSC::ConstructAbility s_readableStreamDefaultReaderReleaseLockCodeConstructAbility;
extern const char* s_readableStreamDefaultReaderClosedCode;
extern const int s_readableStreamDefaultReaderClosedCodeLength;
extern const JSC::ConstructAbility s_readableStreamDefaultReaderClosedCodeConstructAbility;

#define WEBCORE_FOREACH_READABLESTREAMDEFAULTREADER_BUILTIN_DATA(macro) \
    macro(cancel, readableStreamDefaultReaderCancel, 1) \
    macro(read, readableStreamDefaultReaderRead, 0) \
    macro(releaseLock, readableStreamDefaultReaderReleaseLock, 0) \
    macro(closed, readableStreamDefaultReaderClosed, 0) \

#define WEBCORE_BUILTIN_READABLESTREAMDEFAULTREADER_CANCEL 1
#define WEBCORE_BUILTIN_READABLESTREAMDEFAULTREADER_READ 1
#define WEBCORE_BUILTIN_READABLESTREAMDEFAULTREADER_RELEASELOCK 1
#define WEBCORE_BUILTIN_READABLESTREAMDEFAULTREADER_CLOSED 1

#define WEBCORE_FOREACH_READABLESTREAMDEFAULTREADER_BUILTIN_CODE(macro) \
    macro(readableStreamDefaultReaderCancelCode, cancel, s_readableStreamDefaultReaderCancelCodeLength) \
    macro(readableStreamDefaultReaderReadCode, read, s_readableStreamDefaultReaderReadCodeLength) \
    macro(readableStreamDefaultReaderReleaseLockCode, releaseLock, s_readableStreamDefaultReaderReleaseLockCodeLength) \
    macro(readableStreamDefaultReaderClosedCode, closed, s_readableStreamDefaultReaderClosedCodeLength) \

#define WEBCORE_FOREACH_READABLESTREAMDEFAULTREADER_BUILTIN_FUNCTION_NAME(macro) \
    macro(cancel) \
    macro(closed) \
    macro(read) \
    macro(releaseLock) \

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

WEBCORE_FOREACH_READABLESTREAMDEFAULTREADER_BUILTIN_CODE(DECLARE_BUILTIN_GENERATOR)
#undef DECLARE_BUILTIN_GENERATOR

class ReadableStreamDefaultReaderBuiltinsWrapper : private JSC::WeakHandleOwner {
public:
    explicit ReadableStreamDefaultReaderBuiltinsWrapper(JSC::VM* vm)
        : m_vm(*vm)
        WEBCORE_FOREACH_READABLESTREAMDEFAULTREADER_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_READABLESTREAMDEFAULTREADER_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_READABLESTREAMDEFAULTREADER_BUILTIN_CODE(EXPOSE_BUILTIN_EXECUTABLES)
#undef EXPOSE_BUILTIN_EXECUTABLES

    WEBCORE_FOREACH_READABLESTREAMDEFAULTREADER_BUILTIN_FUNCTION_NAME(DECLARE_BUILTIN_IDENTIFIER_ACCESSOR)

    void exportNames();

private:
    JSC::VM& m_vm;

    WEBCORE_FOREACH_READABLESTREAMDEFAULTREADER_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_READABLESTREAMDEFAULTREADER_BUILTIN_CODE(DECLARE_BUILTIN_SOURCE_MEMBERS)
#undef DECLARE_BUILTIN_SOURCE_MEMBERS

};

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

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

} // namespace WebCore

#endif // ENABLE(READABLE_STREAM_API)
