/*
 *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
 *  Copyright (C) 2003-2017 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.
 *
 */

#pragma once

#include "CallFrame.h"
#include <wtf/CheckedArithmetic.h>
#include <wtf/ForbidHeapAllocation.h>
#include <wtf/HashSet.h>

namespace JSC {

class MarkedArgumentBuffer : public RecordOverflow {
    WTF_MAKE_NONCOPYABLE(MarkedArgumentBuffer);
    WTF_MAKE_NONMOVABLE(MarkedArgumentBuffer);
    WTF_FORBID_HEAP_ALLOCATION;
    friend class VM;
    friend class ArgList;

public:
    using Base = RecordOverflow;
    static constexpr size_t inlineCapacity = 8;
    typedef HashSet<MarkedArgumentBuffer*> ListSet;

    // 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_size(0)
        , m_capacity(inlineCapacity)
        , m_buffer(m_inlineBuffer)
        , m_markSet(nullptr)
    {
    }

    ~MarkedArgumentBuffer()
    {
        ASSERT(!m_needsOverflowCheck);
        if (m_markSet)
            m_markSet->remove(this);

        if (EncodedJSValue* base = mallocBase())
            Gigacage::free(Gigacage::JSValue, base);
    }

    size_t size() const { return m_size; }
    bool isEmpty() const { return !m_size; }

    JSValue at(int i) const
    {
        if (i >= m_size)
            return jsUndefined();

        return JSValue::decode(slotFor(i));
    }

    void clear()
    {
        ASSERT(!m_needsOverflowCheck);
        clearOverflow();
        m_size = 0;
    }

    enum OverflowCheckAction {
        CrashOnOverflow,
        WillCheckLater
    };
    template<OverflowCheckAction action>
    void appendWithAction(JSValue v)
    {
        ASSERT(m_size <= m_capacity);
        if (m_size == m_capacity || mallocBase()) {
            slowAppend(v);
            if (action == CrashOnOverflow)
                RELEASE_ASSERT(!hasOverflowed());
            return;
        }

        slotFor(m_size) = JSValue::encode(v);
        ++m_size;
    }
    void append(JSValue v) { appendWithAction<WillCheckLater>(v); }
    void appendWithCrashOnOverflow(JSValue v) { appendWithAction<CrashOnOverflow>(v); }

    void removeLast()
    { 
        ASSERT(m_size);
        m_size--;
    }

    JSValue last() 
    {
        ASSERT(m_size);
        return JSValue::decode(slotFor(m_size - 1));
    }

    JSValue takeLast()
    {
        JSValue result = last();
        removeLast();
        return result;
    }
        
    static void markLists(SlotVisitor&, ListSet&);

    void ensureCapacity(size_t requestedCapacity)
    {
        if (requestedCapacity > static_cast<size_t>(m_capacity))
            slowEnsureCapacity(requestedCapacity);
    }

    bool hasOverflowed()
    {
        clearNeedsOverflowCheck();
        return Base::hasOverflowed();
    }

    void overflowCheckNotNeeded() { clearNeedsOverflowCheck(); }

    template<typename Functor>
    void fill(size_t count, const Functor& func)
    {
        ASSERT(!m_size);
        ensureCapacity(count);
        if (Base::hasOverflowed())
            return;
        m_size = count;
        func(reinterpret_cast<JSValue*>(&slotFor(0)));
    }

private:
    void expandCapacity();
    void expandCapacity(int newCapacity);
    void slowEnsureCapacity(size_t requestedCapacity);

    void addMarkSet(JSValue);

    JS_EXPORT_PRIVATE void slowAppend(JSValue);

    EncodedJSValue& slotFor(int item) const
    {
        return m_buffer[item];
    }
        
    EncodedJSValue* mallocBase()
    {
        if (m_buffer == m_inlineBuffer)
            return nullptr;
        return &slotFor(0);
    }

#if ASSERT_ENABLED
    void setNeedsOverflowCheck() { m_needsOverflowCheck = true; }
    void clearNeedsOverflowCheck() { m_needsOverflowCheck = false; }

    bool m_needsOverflowCheck { false };
#else
    void setNeedsOverflowCheck() { }
    void clearNeedsOverflowCheck() { }
#endif // ASSERT_ENABLED
    int m_size;
    int m_capacity;
    EncodedJSValue m_inlineBuffer[inlineCapacity];
    EncodedJSValue* m_buffer;
    ListSet* m_markSet;
};

class ArgList {
    WTF_MAKE_FAST_ALLOCATED;
    friend class Interpreter;
    friend class JIT;
public:
    ArgList()
        : m_args(nullptr)
        , m_argCount(0)
    {
    }

    ArgList(CallFrame* callFrame)
        : m_args(reinterpret_cast<JSValue*>(&callFrame[CallFrame::argumentOffset(0)]))
        , m_argCount(callFrame->argumentCount())
    {
    }

    ArgList(const MarkedArgumentBuffer& args)
        : m_args(reinterpret_cast<JSValue*>(args.m_buffer))
        , m_argCount(args.size())
    {
    }

    JSValue at(int i) const
    {
        if (i >= m_argCount)
            return jsUndefined();
        return m_args[i];
    }

    bool isEmpty() const { return !m_argCount; }
    size_t size() const { return m_argCount; }
        
    JS_EXPORT_PRIVATE void getSlice(int startIndex, ArgList& result) const;

private:
    JSValue* data() const { return m_args; }

    JSValue* m_args;
    int m_argCount;
};

} // namespace JSC
