/* -*- 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_Compactbuffer_h
#define jit_Compactbuffer_h

#include "jsalloc.h"

#include "jit/IonTypes.h"
#include "js/Vector.h"

namespace js {
namespace jit {

class CompactBufferWriter;

// CompactBuffers are byte streams designed for compressable integers. It has
// helper functions for writing bytes, fixed-size integers, and variable-sized
// integers. Variable sized integers are encoded in 1-5 bytes, each byte
// containing 7 bits of the integer and a bit which specifies whether the next
// byte is also part of the integer.
//
// Fixed-width integers are also available, in case the actual value will not
// be known until later.

class CompactBufferReader
{
    const uint8_t* buffer_;
    const uint8_t* end_;

    uint32_t readVariableLength() {
        uint32_t val = 0;
        uint32_t shift = 0;
        uint8_t byte;
        while (true) {
            MOZ_ASSERT(shift < 32);
            byte = readByte();
            val |= (uint32_t(byte) >> 1) << shift;
            shift += 7;
            if (!(byte & 1))
                return val;
        }
    }

  public:
    CompactBufferReader(const uint8_t* start, const uint8_t* end)
      : buffer_(start),
        end_(end)
    { }
    inline explicit CompactBufferReader(const CompactBufferWriter& writer);
    uint8_t readByte() {
        MOZ_ASSERT(buffer_ < end_);
        return *buffer_++;
    }
    uint32_t readFixedUint32_t() {
        uint32_t b0 = readByte();
        uint32_t b1 = readByte();
        uint32_t b2 = readByte();
        uint32_t b3 = readByte();
        return b0 | (b1 << 8) | (b2 << 16) | (b3 << 24);
    }
    uint16_t readFixedUint16_t() {
        uint32_t b0 = readByte();
        uint32_t b1 = readByte();
        return b0 | (b1 << 8);
    }
    uint32_t readNativeEndianUint32_t() {
        // Must be at 4-byte boundary
        MOZ_ASSERT(uintptr_t(buffer_) % sizeof(uint32_t) == 0);
        return *reinterpret_cast<const uint32_t*>(buffer_);
    }
    uint32_t readUnsigned() {
        return readVariableLength();
    }
    int32_t readSigned() {
        uint8_t b = readByte();
        bool isNegative = !!(b & (1 << 0));
        bool more = !!(b & (1 << 1));
        int32_t result = b >> 2;
        if (more)
            result |= readUnsigned() << 6;
        if (isNegative)
            return -result;
        return result;
    }

    bool more() const {
        MOZ_ASSERT(buffer_ <= end_);
        return buffer_ < end_;
    }

    void seek(const uint8_t* start, uint32_t offset) {
        buffer_ = start + offset;
        MOZ_ASSERT(start < end_);
        MOZ_ASSERT(buffer_ < end_);
    }

    const uint8_t* currentPosition() const {
        return buffer_;
    }
};

class CompactBufferWriter
{
    js::Vector<uint8_t, 32, SystemAllocPolicy> buffer_;
    bool enoughMemory_;

  public:
    CompactBufferWriter()
      : enoughMemory_(true)
    { }

    void setOOM() {
        enoughMemory_ = false;
    }

    // Note: writeByte() takes uint32 to catch implicit casts with a runtime
    // assert.
    void writeByte(uint32_t byte) {
        MOZ_ASSERT(byte <= 0xFF);
        enoughMemory_ &= buffer_.append(byte);
    }
    void writeByteAt(uint32_t pos, uint32_t byte) {
        MOZ_ASSERT(byte <= 0xFF);
        if (!oom())
            buffer_[pos] = byte;
    }
    void writeUnsigned(uint32_t value) {
        do {
            uint8_t byte = ((value & 0x7F) << 1) | (value > 0x7F);
            writeByte(byte);
            value >>= 7;
        } while (value);
    }
    void writeUnsignedAt(uint32_t pos, uint32_t value, uint32_t original) {
        MOZ_ASSERT(value <= original);
        do {
            uint8_t byte = ((value & 0x7F) << 1) | (original > 0x7F);
            writeByteAt(pos++, byte);
            value >>= 7;
            original >>= 7;
        } while (original);
    }
    void writeSigned(int32_t v) {
        bool isNegative = v < 0;
        uint32_t value = isNegative ? -v : v;
        uint8_t byte = ((value & 0x3F) << 2) | ((value > 0x3F) << 1) | uint32_t(isNegative);
        writeByte(byte);

        // Write out the rest of the bytes, if needed.
        value >>= 6;
        if (value == 0)
            return;
        writeUnsigned(value);
    }
    void writeFixedUint32_t(uint32_t value) {
        writeByte(value & 0xFF);
        writeByte((value >> 8) & 0xFF);
        writeByte((value >> 16) & 0xFF);
        writeByte((value >> 24) & 0xFF);
    }
    void writeFixedUint16_t(uint16_t value) {
        writeByte(value & 0xFF);
        writeByte(value >> 8);
    }
    void writeNativeEndianUint32_t(uint32_t value) {
        // Must be at 4-byte boundary
        MOZ_ASSERT_IF(!oom(), length() % sizeof(uint32_t) == 0);
        writeFixedUint32_t(0);
        if (oom())
            return;
        uint8_t* endPtr = buffer() + length();
        reinterpret_cast<uint32_t*>(endPtr)[-1] = value;
    }
    size_t length() const {
        return buffer_.length();
    }
    uint8_t* buffer() {
        MOZ_ASSERT(!oom());
        return &buffer_[0];
    }
    const uint8_t* buffer() const {
        MOZ_ASSERT(!oom());
        return &buffer_[0];
    }
    bool oom() const {
        return !enoughMemory_;
    }
};

CompactBufferReader::CompactBufferReader(const CompactBufferWriter& writer)
  : buffer_(writer.buffer()),
    end_(writer.buffer() + writer.length())
{
}

} // namespace jit
} // namespace js

#endif /* jit_Compactbuffer_h */
