/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim: set ts=8 sts=4 et sw=4 tw=99:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef jit_shared_IonAssemblerBuffer_h
#define jit_shared_IonAssemblerBuffer_h
// needed for the definition of Label :(
#include "jit/shared/Assembler-shared.h"

namespace js {
namespace jit {

// This should theoretically reside inside of AssemblerBuffer, but that won't be nice
// AssemblerBuffer is templated, BufferOffset would be indirectly.
// A BufferOffset is the offset into a buffer, expressed in bytes of instructions.

class BufferOffset
{
    int offset;
  public:
    friend BufferOffset nextOffset();
    explicit BufferOffset(int offset_) : offset(offset_) {}
    // Return the offset as a raw integer.
    int getOffset() const { return offset; }

    // A BOffImm is a Branch Offset Immediate. It is an architecture-specific
    // structure that holds the immediate for a pc relative branch.
    // diffB takes the label for the destination of the branch, and encodes
    // the immediate for the branch.  This will need to be fixed up later, since
    // A pool may be inserted between the branch and its destination
    template <class BOffImm>
    BOffImm diffB(BufferOffset other) const {
        return BOffImm(offset - other.offset);
    }

    template <class BOffImm>
    BOffImm diffB(Label *other) const {
        JS_ASSERT(other->bound());
        return BOffImm(offset - other->offset());
    }

    explicit BufferOffset(Label *l) : offset(l->offset()) {
    }
    explicit BufferOffset(RepatchLabel *l) : offset(l->offset()) {
    }

    BufferOffset() : offset(INT_MIN) {}
    bool assigned() const { return offset != INT_MIN; };
};

template<int SliceSize>
struct BufferSlice : public InlineForwardListNode<BufferSlice<SliceSize> > {
  protected:
    // How much data has been added to the current node.
    uint32_t nodeSize;
  public:
    BufferSlice *getNext() { return static_cast<BufferSlice *>(this->next); }
    void setNext(BufferSlice<SliceSize> *next_) {
        JS_ASSERT(this->next == NULL);
        this->next = next_;
    }
    uint8_t instructions [SliceSize];
    unsigned int size() {
        return nodeSize;
    }
    BufferSlice() : InlineForwardListNode<BufferSlice<SliceSize> >(NULL), nodeSize(0) {}
    void putBlob(uint32_t instSize, uint8_t* inst) {
        if (inst != NULL)
            memcpy(&instructions[size()], inst, instSize);
        nodeSize += instSize;
    }
};

template<int SliceSize, class Inst>
struct AssemblerBuffer
{
  public:
    AssemblerBuffer() : head(NULL), tail(NULL), m_oom(false), m_bail(false), bufferSize(0), LifoAlloc_(8192) {}
  protected:
    typedef BufferSlice<SliceSize> Slice;
    typedef AssemblerBuffer<SliceSize, Inst> AssemblerBuffer_;
    Slice *head;
    Slice *tail;
  public:
    bool m_oom;
    bool m_bail;
    // How much data has been added to the buffer thusfar.
    uint32_t bufferSize;
    uint32_t lastInstSize;
    bool isAligned(int alignment) const {
        // make sure the requested alignment is a power of two.
        JS_ASSERT((alignment & (alignment-1)) == 0);
        return !(size() & (alignment - 1));
    }
    virtual Slice *newSlice(LifoAlloc &a) {
        Slice *tmp = static_cast<Slice*>(a.alloc(sizeof(Slice)));
        if (!tmp) {
            m_oom = true;
            return NULL;
        }
        new (tmp) Slice;
        return tmp;
    }
    bool ensureSpace(int size) {
        if (tail != NULL && tail->size()+size <= SliceSize)
            return true;
        Slice *tmp = newSlice(LifoAlloc_);
        if (tmp == NULL)
            return false;
        if (tail != NULL) {
            bufferSize += tail->size();
            tail->setNext(tmp);
        }
        tail = tmp;
        if (head == NULL)
            head = tmp;
        return true;
    }

    BufferOffset putByte(uint8_t value) {
        return putBlob(sizeof(value), (uint8_t*)&value);
    }

    BufferOffset putShort(uint16_t value) {
        return putBlob(sizeof(value), (uint8_t*)&value);
    }

    BufferOffset putInt(uint32_t value) {
        return putBlob(sizeof(value), (uint8_t*)&value);
    }
    BufferOffset putBlob(uint32_t instSize, uint8_t *inst) {
        if (!ensureSpace(instSize))
            return BufferOffset();
        BufferOffset ret = nextOffset();
        tail->putBlob(instSize, inst);
        return ret;
    }
    unsigned int size() const {
        int executableSize;
        if (tail != NULL)
            executableSize = bufferSize + tail->size();
        else
            executableSize = bufferSize;
        return executableSize;
    }
    unsigned int uncheckedSize() const {
        return size();
    }
    bool oom() const {
        return m_oom || m_bail;
    }
    bool bail() const {
        return m_bail;
    }
    void fail_oom() {
        m_oom = true;
    }
    void fail_bail() {
        m_bail = true;
    }
    Inst *getInst(BufferOffset off) {
        unsigned int local_off = off.getOffset();
        Slice *cur = NULL;
        if (local_off > bufferSize) {
            local_off -= bufferSize;
            cur = tail;
        } else {
            for (cur = head; cur != NULL; cur = cur->getNext()) {
                if (local_off < cur->size())
                    break;
                local_off -= cur->size();
            }
            JS_ASSERT(cur != NULL);
        }
        // the offset within this node should not be larger than the node itself.
        JS_ASSERT(local_off < cur->size());
        return (Inst*)&cur->instructions[local_off];
    }
    BufferOffset nextOffset() const {
        if (tail != NULL)
            return BufferOffset(bufferSize + tail->size());
        else
            return BufferOffset(bufferSize);
    }
    BufferOffset prevOffset() const {
        JS_NOT_REACHED("Don't current record lastInstSize");
        return BufferOffset(bufferSize + tail->nodeSize - lastInstSize);
    }

    // Break the instruction stream so we can go back and edit it at this point
    void perforate() {
        Slice *tmp = newSlice(LifoAlloc_);
        if (!tmp)
            m_oom = true;
        bufferSize += tail->size();
        tail->setNext(tmp);
        tail = tmp;
    }

#if defined(JS_CPU_MIPS)
    void executableCopy(uint8_t* dest_) {
        if (this->oom())
            return;

        for (Slice* cur = head; cur != nullptr; cur = cur->getNext()) {
            memcpy(dest_, &cur->instructions, cur->size());
            dest_ += cur->size();
        }
    }
#endif  // defined(JS_CPU_MIPS)

    class AssemblerBufferInstIterator {
      private:
        BufferOffset bo;
        AssemblerBuffer_ *m_buffer;
      public:
        AssemblerBufferInstIterator(BufferOffset off, AssemblerBuffer_ *buff) : bo(off), m_buffer(buff) {}
        Inst *next() {
            Inst *i = m_buffer->getInst(bo);
            bo = BufferOffset(bo.getOffset()+i->size());
            return cur();
        };
        Inst *cur() {
            return m_buffer->getInst(bo);
        }
    };
  public:
    LifoAlloc LifoAlloc_;
};

} // ion
} // js
#endif /* jit_shared_IonAssemblerBuffer_h */
