1// Copyright 2017 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_INTERPRETER_BYTECODE_SOURCE_INFO_H_
6#define V8_INTERPRETER_BYTECODE_SOURCE_INFO_H_
7
8#include "src/common/globals.h"
9
10namespace v8 {
11namespace internal {
12namespace interpreter {
13
14// Source code position information.
15class BytecodeSourceInfo final {
16 public:
17  static const int kUninitializedPosition = -1;
18
19  BytecodeSourceInfo()
20      : position_type_(PositionType::kNone),
21        source_position_(kUninitializedPosition) {}
22
23  BytecodeSourceInfo(int source_position, bool is_statement)
24      : position_type_(is_statement ? PositionType::kStatement
25                                    : PositionType::kExpression),
26        source_position_(source_position) {
27    DCHECK_GE(source_position, 0);
28  }
29
30  // Makes instance into a statement position.
31  void MakeStatementPosition(int source_position) {
32    // Statement positions can be replaced by other statement
33    // positions. For example , "for (x = 0; x < 3; ++x) 7;" has a
34    // statement position associated with 7 but no bytecode associated
35    // with it. Then Next is emitted after the body and has
36    // statement position and overrides the existing one.
37    position_type_ = PositionType::kStatement;
38    source_position_ = source_position;
39  }
40
41  // Makes instance into an expression position. Instance should not
42  // be a statement position otherwise it could be lost and impair the
43  // debugging experience.
44  void MakeExpressionPosition(int source_position) {
45    DCHECK(!is_statement());
46    position_type_ = PositionType::kExpression;
47    source_position_ = source_position;
48  }
49
50  // Forces an instance into an expression position.
51  void ForceExpressionPosition(int source_position) {
52    position_type_ = PositionType::kExpression;
53    source_position_ = source_position;
54  }
55
56  int source_position() const {
57    DCHECK(is_valid());
58    return source_position_;
59  }
60
61  bool is_statement() const {
62    return position_type_ == PositionType::kStatement;
63  }
64  bool is_expression() const {
65    return position_type_ == PositionType::kExpression;
66  }
67
68  bool is_valid() const { return position_type_ != PositionType::kNone; }
69  void set_invalid() {
70    position_type_ = PositionType::kNone;
71    source_position_ = kUninitializedPosition;
72  }
73
74  bool operator==(const BytecodeSourceInfo& other) const {
75    return position_type_ == other.position_type_ &&
76           source_position_ == other.source_position_;
77  }
78
79  bool operator!=(const BytecodeSourceInfo& other) const {
80    return position_type_ != other.position_type_ ||
81           source_position_ != other.source_position_;
82  }
83
84 private:
85  enum class PositionType : uint8_t { kNone, kExpression, kStatement };
86
87  PositionType position_type_;
88  int source_position_;
89};
90
91V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
92                                           const BytecodeSourceInfo& info);
93
94}  // namespace interpreter
95}  // namespace internal
96}  // namespace v8
97
98#endif  // V8_INTERPRETER_BYTECODE_SOURCE_INFO_H_
99