// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <cstring>
#include <iomanip>

#include "src/codegen/assembler-inl.h"
#include "src/codegen/code-comments.h"

namespace v8 {
namespace internal {

namespace {
static constexpr uint8_t kOffsetToFirstCommentEntry = kUInt32Size;
static constexpr uint8_t kOffsetToPCOffset = 0;
static constexpr uint8_t kOffsetToCommentSize = kOffsetToPCOffset + kUInt32Size;
static constexpr uint8_t kOffsetToCommentString =
    kOffsetToCommentSize + kUInt32Size;
}  // namespace

uint32_t CodeCommentEntry::comment_length() const {
  return static_cast<uint32_t>(comment.size() + 1);
}

uint32_t CodeCommentEntry::size() const {
  return kOffsetToCommentString + comment_length();
}

CodeCommentsIterator::CodeCommentsIterator(Address code_comments_start,
                                           uint32_t code_comments_size)
    : code_comments_start_(code_comments_start),
      code_comments_size_(code_comments_size),
      current_entry_(code_comments_start + kOffsetToFirstCommentEntry) {
  DCHECK_NE(kNullAddress, code_comments_start);
  DCHECK_IMPLIES(code_comments_size,
                 code_comments_size ==
                     base::ReadUnalignedValue<uint32_t>(code_comments_start_));
}

uint32_t CodeCommentsIterator::size() const { return code_comments_size_; }

const char* CodeCommentsIterator::GetComment() const {
  const char* comment_string =
      reinterpret_cast<const char*>(current_entry_ + kOffsetToCommentString);
  CHECK_EQ(GetCommentSize(), strlen(comment_string) + 1);
  return comment_string;
}

uint32_t CodeCommentsIterator::GetCommentSize() const {
  return ReadUnalignedValue<uint32_t>(current_entry_ + kOffsetToCommentSize);
}

uint32_t CodeCommentsIterator::GetPCOffset() const {
  return ReadUnalignedValue<uint32_t>(current_entry_ + kOffsetToPCOffset);
}

void CodeCommentsIterator::Next() {
  current_entry_ += kOffsetToCommentString + GetCommentSize();
}

bool CodeCommentsIterator::HasCurrent() const {
  return current_entry_ < code_comments_start_ + size();
}

void CodeCommentsWriter::Emit(Assembler* assm) {
  assm->dd(section_size());
  for (auto i = comments_.begin(); i != comments_.end(); ++i) {
    assm->dd(i->pc_offset);
    assm->dd(i->comment_length());
    for (char c : i->comment) {
      EnsureSpace ensure_space(assm);
      assm->db(c);
    }
    assm->db('\0');
  }
}

void CodeCommentsWriter::Add(uint32_t pc_offset, std::string comment) {
  CodeCommentEntry entry = {pc_offset, std::move(comment)};
  byte_count_ += entry.size();
  comments_.push_back(std::move(entry));
}

size_t CodeCommentsWriter::entry_count() const { return comments_.size(); }
uint32_t CodeCommentsWriter::section_size() const {
  return kOffsetToFirstCommentEntry + static_cast<uint32_t>(byte_count_);
}

void PrintCodeCommentsSection(std::ostream& out, Address code_comments_start,
                              uint32_t code_comments_size) {
  CodeCommentsIterator it(code_comments_start, code_comments_size);
  out << "CodeComments (size = " << it.size() << ")\n";
  if (it.HasCurrent()) {
    out << std::setw(6) << "pc" << std::setw(6) << "len"
        << " comment\n";
  }
  for (; it.HasCurrent(); it.Next()) {
    out << std::hex << std::setw(6) << it.GetPCOffset() << std::dec
        << std::setw(6) << it.GetCommentSize() << " (" << it.GetComment()
        << ")\n";
  }
}

}  // namespace internal
}  // namespace v8
