// Copyright 2015 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 "src/interpreter/bytecode-pipeline.h"

#include <iomanip>
#include "src/interpreter/source-position-table.h"

namespace v8 {
namespace internal {
namespace interpreter {

BytecodeNode::BytecodeNode(Bytecode bytecode) {
  DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0);
  bytecode_ = bytecode;
}

BytecodeNode::BytecodeNode(Bytecode bytecode, uint32_t operand0) {
  DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 1);
  bytecode_ = bytecode;
  operands_[0] = operand0;
}

BytecodeNode::BytecodeNode(Bytecode bytecode, uint32_t operand0,
                           uint32_t operand1) {
  DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 2);
  bytecode_ = bytecode;
  operands_[0] = operand0;
  operands_[1] = operand1;
}

BytecodeNode::BytecodeNode(Bytecode bytecode, uint32_t operand0,
                           uint32_t operand1, uint32_t operand2) {
  DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 3);
  bytecode_ = bytecode;
  operands_[0] = operand0;
  operands_[1] = operand1;
  operands_[2] = operand2;
}

BytecodeNode::BytecodeNode(Bytecode bytecode, uint32_t operand0,
                           uint32_t operand1, uint32_t operand2,
                           uint32_t operand3) {
  DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 4);
  bytecode_ = bytecode;
  operands_[0] = operand0;
  operands_[1] = operand1;
  operands_[2] = operand2;
  operands_[3] = operand3;
}

BytecodeNode::BytecodeNode(const BytecodeNode& other) {
  memcpy(this, &other, sizeof(other));
}

BytecodeNode& BytecodeNode::operator=(const BytecodeNode& other) {
  memcpy(this, &other, sizeof(other));
  return *this;
}

void BytecodeNode::set_bytecode(Bytecode bytecode) {
  DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0);
  bytecode_ = bytecode;
}

void BytecodeNode::set_bytecode(Bytecode bytecode, uint32_t operand0) {
  DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 1);
  bytecode_ = bytecode;
  operands_[0] = operand0;
}

void BytecodeNode::Clone(const BytecodeNode* const other) {
  memcpy(this, other, sizeof(*other));
}

void BytecodeNode::Print(std::ostream& os) const {
#ifdef DEBUG
  std::ios saved_state(nullptr);
  saved_state.copyfmt(os);
  os << Bytecodes::ToString(bytecode_);

  for (int i = 0; i < operand_count(); ++i) {
    os << ' ' << std::setw(8) << std::setfill('0') << std::hex << operands_[i];
  }
  os.copyfmt(saved_state);

  if (source_info_.is_valid()) {
    os << ' ' << source_info_;
  }
  os << '\n';
#else
  os << static_cast<const void*>(this);
#endif  // DEBUG
}

void BytecodeNode::Transform(Bytecode new_bytecode, uint32_t extra_operand) {
  DCHECK_EQ(Bytecodes::NumberOfOperands(new_bytecode),
            Bytecodes::NumberOfOperands(bytecode()) + 1);
  DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 1 ||
         Bytecodes::GetOperandType(new_bytecode, 0) ==
             Bytecodes::GetOperandType(bytecode(), 0));
  DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 2 ||
         Bytecodes::GetOperandType(new_bytecode, 1) ==
             Bytecodes::GetOperandType(bytecode(), 1));
  DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 3 ||
         Bytecodes::GetOperandType(new_bytecode, 2) ==
             Bytecodes::GetOperandType(bytecode(), 2));
  DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 4);
  operands_[operand_count()] = extra_operand;
  bytecode_ = new_bytecode;
}

bool BytecodeNode::operator==(const BytecodeNode& other) const {
  if (this == &other) {
    return true;
  } else if (this->bytecode() != other.bytecode() ||
             this->source_info() != other.source_info()) {
    return false;
  } else {
    for (int i = 0; i < this->operand_count(); ++i) {
      if (this->operand(i) != other.operand(i)) {
        return false;
      }
    }
  }
  return true;
}

std::ostream& operator<<(std::ostream& os, const BytecodeSourceInfo& info) {
  if (info.is_valid()) {
    char description = info.is_statement() ? 'S' : 'E';
    os << info.source_position() << ' ' << description << '>';
  }
  return os;
}

std::ostream& operator<<(std::ostream& os, const BytecodeNode& node) {
  node.Print(os);
  return os;
}

}  // namespace interpreter
}  // namespace internal
}  // namespace v8
