// Copyright 2017 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.

#ifndef V8_INTERPRETER_BYTECODE_SOURCE_INFO_H_
#define V8_INTERPRETER_BYTECODE_SOURCE_INFO_H_

#include "src/common/globals.h"

namespace v8 {
namespace internal {
namespace interpreter {

// Source code position information.
class BytecodeSourceInfo final {
 public:
  static const int kUninitializedPosition = -1;

  BytecodeSourceInfo()
      : position_type_(PositionType::kNone),
        source_position_(kUninitializedPosition) {}

  BytecodeSourceInfo(int source_position, bool is_statement)
      : position_type_(is_statement ? PositionType::kStatement
                                    : PositionType::kExpression),
        source_position_(source_position) {
    DCHECK_GE(source_position, 0);
  }

  // Makes instance into a statement position.
  void MakeStatementPosition(int source_position) {
    // Statement positions can be replaced by other statement
    // positions. For example , "for (x = 0; x < 3; ++x) 7;" has a
    // statement position associated with 7 but no bytecode associated
    // with it. Then Next is emitted after the body and has
    // statement position and overrides the existing one.
    position_type_ = PositionType::kStatement;
    source_position_ = source_position;
  }

  // Makes instance into an expression position. Instance should not
  // be a statement position otherwise it could be lost and impair the
  // debugging experience.
  void MakeExpressionPosition(int source_position) {
    DCHECK(!is_statement());
    position_type_ = PositionType::kExpression;
    source_position_ = source_position;
  }

  // Forces an instance into an expression position.
  void ForceExpressionPosition(int source_position) {
    position_type_ = PositionType::kExpression;
    source_position_ = source_position;
  }

  int source_position() const {
    DCHECK(is_valid());
    return source_position_;
  }

  bool is_statement() const {
    return position_type_ == PositionType::kStatement;
  }
  bool is_expression() const {
    return position_type_ == PositionType::kExpression;
  }

  bool is_valid() const { return position_type_ != PositionType::kNone; }
  void set_invalid() {
    position_type_ = PositionType::kNone;
    source_position_ = kUninitializedPosition;
  }

  bool operator==(const BytecodeSourceInfo& other) const {
    return position_type_ == other.position_type_ &&
           source_position_ == other.source_position_;
  }

  bool operator!=(const BytecodeSourceInfo& other) const {
    return position_type_ != other.position_type_ ||
           source_position_ != other.source_position_;
  }

 private:
  enum class PositionType : uint8_t { kNone, kExpression, kStatement };

  PositionType position_type_;
  int source_position_;
};

V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
                                           const BytecodeSourceInfo& info);

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

#endif  // V8_INTERPRETER_BYTECODE_SOURCE_INFO_H_
