/*
 *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
 *  Copyright (C) 2003, 2007, 2008, 2009 Apple Inc. All rights reserved.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Library General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public License
 *  along with this library; see the file COPYING.LIB.  If not, write to
 *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 *  Boston, MA 02110-1301, USA.
 *
 */

#ifndef ArgList_h
#define ArgList_h

#include "Register.h"
#include <wtf/HashSet.h>
#include <wtf/Noncopyable.h>
#include <wtf/Vector.h>

namespace JSC {

    class MarkStack;

    class MarkedArgumentBuffer : public Noncopyable {
    private:
        static const unsigned inlineCapacity = 8;
        typedef Vector<Register, inlineCapacity> VectorType;
        typedef HashSet<MarkedArgumentBuffer*> ListSet;

    public:
        typedef VectorType::iterator iterator;
        typedef VectorType::const_iterator const_iterator;

        // Constructor for a read-write list, to which you may append values.
        // FIXME: Remove all clients of this API, then remove this API.
        MarkedArgumentBuffer()
            : m_isUsingInlineBuffer(true)
            , m_markSet(0)
#ifndef NDEBUG
            , m_isReadOnly(false)
#endif
        {
            m_buffer = m_vector.data();
            m_size = 0;
        }

        // Constructor for a read-only list whose data has already been allocated elsewhere.
        MarkedArgumentBuffer(Register* buffer, size_t size)
            : m_buffer(buffer)
            , m_size(size)
            , m_isUsingInlineBuffer(true)
            , m_markSet(0)
#ifndef NDEBUG
            , m_isReadOnly(true)
#endif
        {
        }

        void initialize(Register* buffer, size_t size)
        {
            ASSERT(!m_markSet);
            ASSERT(isEmpty());

            m_buffer = buffer;
            m_size = size;
#ifndef NDEBUG
            m_isReadOnly = true;
#endif
        }

        ~MarkedArgumentBuffer()
        {
            if (m_markSet)
                m_markSet->remove(this);
        }

        size_t size() const { return m_size; }
        bool isEmpty() const { return !m_size; }

        JSValue at(size_t i) const
        {
            if (i < m_size)
                return m_buffer[i].jsValue();
            return jsUndefined();
        }

        void clear()
        {
            m_vector.clear();
            m_buffer = 0;
            m_size = 0;
        }

        void append(JSValue v)
        {
            ASSERT(!m_isReadOnly);

#if ENABLE(JSC_ZOMBIES)
            ASSERT(!v.isZombie());
#endif

            if (m_isUsingInlineBuffer && m_size < inlineCapacity) {
                m_vector.uncheckedAppend(v);
                ++m_size;
            } else {
                // Putting this case all in one function measurably improves
                // the performance of the fast "just append to inline buffer" case.
                slowAppend(v);
                ++m_size;
                m_isUsingInlineBuffer = false;
            }
        }

        void removeLast()
        { 
            ASSERT(m_size);
            m_size--;
            m_vector.removeLast();
        }

        JSValue last() 
        {
            ASSERT(m_size);
            return m_buffer[m_size - 1].jsValue();
        }
        
        iterator begin() { return m_buffer; }
        iterator end() { return m_buffer + m_size; }

        const_iterator begin() const { return m_buffer; }
        const_iterator end() const { return m_buffer + m_size; }

        static void markLists(MarkStack&, ListSet&);

    private:
        void slowAppend(JSValue);
        
        Register* m_buffer;
        size_t m_size;
        bool m_isUsingInlineBuffer;

        VectorType m_vector;
        ListSet* m_markSet;
#ifndef NDEBUG
        bool m_isReadOnly;
#endif

    private:
        // Prohibits new / delete, which would break GC.
        friend class JSGlobalData;
        
        void* operator new(size_t size)
        {
            return fastMalloc(size);
        }
        void operator delete(void* p)
        {
            fastFree(p);
        }

        void* operator new[](size_t);
        void operator delete[](void*);

        void* operator new(size_t, void*);
        void operator delete(void*, size_t);
    };

    class ArgList {
        friend class JIT;
    public:
        typedef JSValue* iterator;
        typedef const JSValue* const_iterator;

        ArgList()
            : m_args(0)
            , m_argCount(0)
        {
        }
        
        ArgList(JSValue* args, unsigned argCount)
            : m_args(args)
            , m_argCount(argCount)
        {
#if ENABLE(JSC_ZOMBIES)
            for (size_t i = 0; i < argCount; i++)
                ASSERT(!m_args[i].isZombie());
#endif
        }
        
        ArgList(Register* args, int argCount)
            : m_args(reinterpret_cast<JSValue*>(args))
            , m_argCount(argCount)
        {
            ASSERT(argCount >= 0);
        }

        ArgList(const MarkedArgumentBuffer& args)
            : m_args(reinterpret_cast<JSValue*>(const_cast<Register*>(args.begin())))
            , m_argCount(args.size())
        {
        }

        JSValue at(size_t idx) const
        {
            if (idx < m_argCount)
                return m_args[idx];
            return jsUndefined();
        }

        bool isEmpty() const { return !m_argCount; }

        size_t size() const { return m_argCount; }
        
        iterator begin() { return m_args; }
        iterator end() { return m_args + m_argCount; }
        
        const_iterator begin() const { return m_args; }
        const_iterator end() const { return m_args + m_argCount; }

        void getSlice(int startIndex, ArgList& result) const;
    private:
        JSValue* m_args;
        size_t m_argCount;
    };

} // namespace JSC

#endif // ArgList_h
