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 
10 namespace v8 {
11 namespace internal {
12 namespace interpreter {
13 
14 // Source code position information.
15 class BytecodeSourceInfo final {
16  public:
17   static const int kUninitializedPosition = -1;
18 
BytecodeSourceInfo()19   BytecodeSourceInfo()
20       : position_type_(PositionType::kNone),
21         source_position_(kUninitializedPosition) {}
22 
BytecodeSourceInfo(int source_position,bool is_statement)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.
MakeStatementPosition(int source_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.
MakeExpressionPosition(int source_position)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.
ForceExpressionPosition(int source_position)51   void ForceExpressionPosition(int source_position) {
52     position_type_ = PositionType::kExpression;
53     source_position_ = source_position;
54   }
55 
source_position()56   int source_position() const {
57     DCHECK(is_valid());
58     return source_position_;
59   }
60 
is_statement()61   bool is_statement() const {
62     return position_type_ == PositionType::kStatement;
63   }
is_expression()64   bool is_expression() const {
65     return position_type_ == PositionType::kExpression;
66   }
67 
is_valid()68   bool is_valid() const { return position_type_ != PositionType::kNone; }
set_invalid()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 
91 V8_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