//==- Deserialize.cpp - Generic Object Serialization to Bitcode --*- C++ -*-==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the internal methods used for object serialization.
//
//===----------------------------------------------------------------------===//

#include "llvm/Bitcode/Deserialize.h"

#ifdef DEBUG_BACKPATCH
#include "llvm/Support/Streams.h"
#endif

using namespace llvm;

Deserializer::Deserializer(BitstreamReader& stream)
  : Stream(stream), RecIdx(0), FreeList(NULL), AbbrevNo(0), RecordCode(0) {

    StreamStart = Stream.GetCurrentBitNo();
}

Deserializer::~Deserializer() {
  assert (RecIdx >= Record.size() && 
          "Still scanning bitcode record when deserialization completed.");
 
#ifdef DEBUG_BACKPATCH
  for (MapTy::iterator I=BPatchMap.begin(), E=BPatchMap.end(); I!=E; ++I)
    assert (I->first.hasFinalPtr() &&
            "Some pointers were not backpatched.");
#endif
}


bool Deserializer::inRecord() {
  if (Record.size() > 0) {
    if (RecIdx >= Record.size()) {
      RecIdx = 0;
      Record.clear();
      AbbrevNo = 0;
      return false;
    }
    else
      return true;
  }

  return false;
}

bool Deserializer::AdvanceStream() {
  assert (!inRecord() && 
          "Cannot advance stream.  Still processing a record.");
  
  if (AbbrevNo == bitc::ENTER_SUBBLOCK ||
      AbbrevNo >= bitc::UNABBREV_RECORD)
    return true;
  
  while (!Stream.AtEndOfStream()) {
    
    uint64_t Pos = Stream.GetCurrentBitNo();
    AbbrevNo = Stream.ReadCode();    
  
    switch (AbbrevNo) {        
      case bitc::ENTER_SUBBLOCK: {
        unsigned id = Stream.ReadSubBlockID();
        
        // Determine the extent of the block.  This is useful for jumping around
        // the stream.  This is hack: we read the header of the block, save
        // the length, and then revert the bitstream to a location just before
        // the block is entered.
        uint64_t BPos = Stream.GetCurrentBitNo();
        Stream.ReadVBR(bitc::CodeLenWidth); // Skip the code size.
        Stream.SkipToWord();
        unsigned NumWords = Stream.Read(bitc::BlockSizeWidth);
        Stream.JumpToBit(BPos);
                
        BlockStack.push_back(Location(Pos,id,NumWords));
        break;
      } 
        
      case bitc::END_BLOCK: {
        bool x = Stream.ReadBlockEnd();
        assert (!x && "Error at block end.");
        BlockStack.pop_back();
        continue;
      }
        
      case bitc::DEFINE_ABBREV:
        Stream.ReadAbbrevRecord();
        continue;

      default:
        break;
    }
    
    return true;
  }
  
  return false;
}

void Deserializer::ReadRecord() {

  while (AdvanceStream() && AbbrevNo == bitc::ENTER_SUBBLOCK) {
    assert (!BlockStack.empty());
    Stream.EnterSubBlock(BlockStack.back().BlockID);
    AbbrevNo = 0;
  }

  if (Stream.AtEndOfStream())
    return;
  
  assert (Record.size() == 0);
  assert (AbbrevNo >= bitc::UNABBREV_RECORD);
  RecordCode = Stream.ReadRecord(AbbrevNo,Record);
  assert (Record.size() > 0);
}

void Deserializer::SkipBlock() {
  assert (!inRecord());

  if (AtEnd())
    return;

  AdvanceStream();  

  assert (AbbrevNo == bitc::ENTER_SUBBLOCK);
  BlockStack.pop_back();
  Stream.SkipBlock();

  AbbrevNo = 0;
  AdvanceStream();
}

bool Deserializer::SkipToBlock(unsigned BlockID) {
  assert (!inRecord());
  
  AdvanceStream();
  assert (AbbrevNo == bitc::ENTER_SUBBLOCK);
  
  unsigned BlockLevel = BlockStack.size();

  while (!AtEnd() &&
         BlockLevel == BlockStack.size() && 
         getCurrentBlockID() != BlockID)
    SkipBlock();

  return !(AtEnd() || BlockLevel != BlockStack.size());
}

Deserializer::Location Deserializer::getCurrentBlockLocation() {
  if (!inRecord())
    AdvanceStream();
  
  return BlockStack.back();
}

bool Deserializer::JumpTo(const Location& Loc) {
    
  assert (!inRecord());

  AdvanceStream();
  
  assert (!BlockStack.empty() || AtEnd());
    
  uint64_t LastBPos = StreamStart;
  
  while (!BlockStack.empty()) {
    
    LastBPos = BlockStack.back().BitNo;
    
    // Determine of the current block contains the location of the block
    // we are looking for.
    if (BlockStack.back().contains(Loc)) {
      // We found the enclosing block.  We must first POP it off to
      // destroy any accumulated context within the block scope.  We then
      // jump to the position of the block and enter it.
      Stream.JumpToBit(LastBPos);
      
      if (BlockStack.size() == Stream.BlockScope.size())
        Stream.PopBlockScope();

      BlockStack.pop_back();
      
      AbbrevNo = 0;
      AdvanceStream();      
      assert (AbbrevNo == bitc::ENTER_SUBBLOCK);
      
      Stream.EnterSubBlock(BlockStack.back().BlockID);
      break;
    }

    // This block does not contain the block we are looking for.  Pop it.
    if (BlockStack.size() == Stream.BlockScope.size())
      Stream.PopBlockScope();
    
    BlockStack.pop_back();

  }

  // Check if we have popped our way to the outermost scope.  If so,
  // we need to adjust our position.
  if (BlockStack.empty()) {
    assert (Stream.BlockScope.empty());
    
    Stream.JumpToBit(Loc.BitNo < LastBPos ? StreamStart : LastBPos);
    AbbrevNo = 0;
    AdvanceStream();
  }

  assert (AbbrevNo == bitc::ENTER_SUBBLOCK);
  assert (!BlockStack.empty());
  
  while (!AtEnd() && BlockStack.back() != Loc) {
    if (BlockStack.back().contains(Loc)) {
      Stream.EnterSubBlock(BlockStack.back().BlockID);
      AbbrevNo = 0;
      AdvanceStream();
      continue;
    }
    else
      SkipBlock();
  }
  
  if (AtEnd())
    return false;
  
  assert (BlockStack.back() == Loc);

  return true;
}

void Deserializer::Rewind() {
  while (!Stream.BlockScope.empty())
    Stream.PopBlockScope();
  
  while (!BlockStack.empty())
    BlockStack.pop_back();
  
  Stream.JumpToBit(StreamStart);
  AbbrevNo = 0;
}
  

unsigned Deserializer::getCurrentBlockID() { 
  if (!inRecord())
    AdvanceStream();
  
  return BlockStack.back().BlockID;
}

unsigned Deserializer::getRecordCode() {
  if (!inRecord()) {
    AdvanceStream();
    assert (AbbrevNo >= bitc::UNABBREV_RECORD);
    ReadRecord();
  }
  
  return RecordCode;
}

bool Deserializer::FinishedBlock(Location BlockLoc) {
  if (!inRecord())
    AdvanceStream();

  for (llvm::SmallVector<Location,8>::reverse_iterator
        I=BlockStack.rbegin(), E=BlockStack.rend(); I!=E; ++I)
      if (*I == BlockLoc)
        return false;
  
  return true;
}

unsigned Deserializer::getAbbrevNo() {
  if (!inRecord())
    AdvanceStream();
  
  return AbbrevNo;
}

bool Deserializer::AtEnd() {
  if (inRecord())
    return false;
  
  if (!AdvanceStream())
    return true;
  
  return false;
}

uint64_t Deserializer::ReadInt() {
  // FIXME: Any error recovery/handling with incomplete or bad files?
  if (!inRecord())
    ReadRecord();

  return Record[RecIdx++];
}

int64_t Deserializer::ReadSInt() {
  uint64_t x = ReadInt();
  int64_t magnitude = x >> 1;
  return x & 0x1 ? -magnitude : magnitude;
}

char* Deserializer::ReadCStr(char* cstr, unsigned MaxLen, bool isNullTerm) {
  if (cstr == NULL)
    MaxLen = 0; // Zero this just in case someone does something funny.
  
  unsigned len = ReadInt();

  assert (MaxLen == 0 || (len + (isNullTerm ? 1 : 0)) <= MaxLen);

  if (!cstr)
    cstr = new char[len + (isNullTerm ? 1 : 0)];
  
  assert (cstr != NULL);
  
  for (unsigned i = 0; i < len; ++i)
    cstr[i] = (char) ReadInt();
  
  if (isNullTerm)
    cstr[len+1] = '\0';
  
  return cstr;
}

void Deserializer::ReadCStr(std::vector<char>& buff, bool isNullTerm,
                            unsigned Idx) {
  
  unsigned len = ReadInt();

  // If Idx is beyond the current before size, reduce Idx to refer to the
  // element after the last element.
  if (Idx > buff.size())
    Idx = buff.size();

  buff.reserve(len+Idx);
  buff.resize(Idx);      
  
  for (unsigned i = 0; i < len; ++i)
    buff.push_back((char) ReadInt());
  
  if (isNullTerm)
    buff.push_back('\0');
}

void Deserializer::RegisterPtr(const SerializedPtrID& PtrId,
                               const void* Ptr) {
  
  MapTy::value_type& E = BPatchMap.FindAndConstruct(BPKey(PtrId));
  
  assert (!HasFinalPtr(E) && "Pointer already registered.");

#ifdef DEBUG_BACKPATCH
  llvm::cerr << "RegisterPtr: " << PtrId << " => " << Ptr << "\n";
#endif 
  
  SetPtr(E,Ptr);
}

void Deserializer::ReadUIntPtr(uintptr_t& PtrRef, 
                               const SerializedPtrID& PtrId,
                               bool AllowBackpatch) {  
  if (PtrId == 0) {
    PtrRef = 0;
    return;
  }
  
  MapTy::value_type& E = BPatchMap.FindAndConstruct(BPKey(PtrId));
  
  if (HasFinalPtr(E)) {
    PtrRef = GetFinalPtr(E);

#ifdef DEBUG_BACKPATCH
    llvm::cerr << "ReadUintPtr: " << PtrId
               << " <-- " <<  (void*) GetFinalPtr(E) << '\n';
#endif    
  }
  else {
    assert (AllowBackpatch &&
            "Client forbids backpatching for this pointer.");
    
#ifdef DEBUG_BACKPATCH
    llvm::cerr << "ReadUintPtr: " << PtrId << " (NO PTR YET)\n";
#endif
    
    // Register backpatch.  Check the freelist for a BPNode.
    BPNode* N;

    if (FreeList) {
      N = FreeList;
      FreeList = FreeList->Next;
    }
    else // No available BPNode.  Allocate one.
      N = (BPNode*) Allocator.Allocate<BPNode>();
    
    new (N) BPNode(GetBPNode(E),PtrRef);
    SetBPNode(E,N);
  }
}

uintptr_t Deserializer::ReadInternalRefPtr() {
  SerializedPtrID PtrId = ReadPtrID();
  
  assert (PtrId != 0 && "References cannot refer the NULL address.");

  MapTy::value_type& E = BPatchMap.FindAndConstruct(BPKey(PtrId));
  
  assert (HasFinalPtr(E) &&
          "Cannot backpatch references.  Object must be already deserialized.");
  
  return GetFinalPtr(E);
}

void Deserializer::BPEntry::SetPtr(BPNode*& FreeList, void* P) {
  BPNode* Last = NULL;
  
  for (BPNode* N = Head; N != NULL; N=N->Next) {
    Last = N;
    N->PtrRef |= reinterpret_cast<uintptr_t>(P);
  }
  
  if (Last) {
    Last->Next = FreeList;
    FreeList = Head;
  }
  
  Ptr = const_cast<void*>(P);
}


#define INT_READ(TYPE)\
void SerializeTrait<TYPE>::Read(Deserializer& D, TYPE& X) {\
  X = (TYPE) D.ReadInt(); }

INT_READ(bool)
INT_READ(unsigned char)
INT_READ(unsigned short)
INT_READ(unsigned int)
INT_READ(unsigned long)

#define SINT_READ(TYPE)\
void SerializeTrait<TYPE>::Read(Deserializer& D, TYPE& X) {\
  X = (TYPE) D.ReadSInt(); }

INT_READ(signed char)
INT_READ(signed short)
INT_READ(signed int)
INT_READ(signed long)
