• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 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 #include "src/interpreter/bytecode-pipeline.h"
6 
7 #include <iomanip>
8 #include "src/interpreter/source-position-table.h"
9 
10 namespace v8 {
11 namespace internal {
12 namespace interpreter {
13 
BytecodeNode(Bytecode bytecode)14 BytecodeNode::BytecodeNode(Bytecode bytecode) {
15   DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0);
16   bytecode_ = bytecode;
17 }
18 
BytecodeNode(Bytecode bytecode,uint32_t operand0)19 BytecodeNode::BytecodeNode(Bytecode bytecode, uint32_t operand0) {
20   DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 1);
21   bytecode_ = bytecode;
22   operands_[0] = operand0;
23 }
24 
BytecodeNode(Bytecode bytecode,uint32_t operand0,uint32_t operand1)25 BytecodeNode::BytecodeNode(Bytecode bytecode, uint32_t operand0,
26                            uint32_t operand1) {
27   DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 2);
28   bytecode_ = bytecode;
29   operands_[0] = operand0;
30   operands_[1] = operand1;
31 }
32 
BytecodeNode(Bytecode bytecode,uint32_t operand0,uint32_t operand1,uint32_t operand2)33 BytecodeNode::BytecodeNode(Bytecode bytecode, uint32_t operand0,
34                            uint32_t operand1, uint32_t operand2) {
35   DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 3);
36   bytecode_ = bytecode;
37   operands_[0] = operand0;
38   operands_[1] = operand1;
39   operands_[2] = operand2;
40 }
41 
BytecodeNode(Bytecode bytecode,uint32_t operand0,uint32_t operand1,uint32_t operand2,uint32_t operand3)42 BytecodeNode::BytecodeNode(Bytecode bytecode, uint32_t operand0,
43                            uint32_t operand1, uint32_t operand2,
44                            uint32_t operand3) {
45   DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 4);
46   bytecode_ = bytecode;
47   operands_[0] = operand0;
48   operands_[1] = operand1;
49   operands_[2] = operand2;
50   operands_[3] = operand3;
51 }
52 
BytecodeNode(const BytecodeNode & other)53 BytecodeNode::BytecodeNode(const BytecodeNode& other) {
54   memcpy(this, &other, sizeof(other));
55 }
56 
operator =(const BytecodeNode & other)57 BytecodeNode& BytecodeNode::operator=(const BytecodeNode& other) {
58   memcpy(this, &other, sizeof(other));
59   return *this;
60 }
61 
set_bytecode(Bytecode bytecode)62 void BytecodeNode::set_bytecode(Bytecode bytecode) {
63   DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0);
64   bytecode_ = bytecode;
65 }
66 
set_bytecode(Bytecode bytecode,uint32_t operand0)67 void BytecodeNode::set_bytecode(Bytecode bytecode, uint32_t operand0) {
68   DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 1);
69   bytecode_ = bytecode;
70   operands_[0] = operand0;
71 }
72 
Clone(const BytecodeNode * const other)73 void BytecodeNode::Clone(const BytecodeNode* const other) {
74   memcpy(this, other, sizeof(*other));
75 }
76 
Print(std::ostream & os) const77 void BytecodeNode::Print(std::ostream& os) const {
78 #ifdef DEBUG
79   std::ios saved_state(nullptr);
80   saved_state.copyfmt(os);
81   os << Bytecodes::ToString(bytecode_);
82 
83   for (int i = 0; i < operand_count(); ++i) {
84     os << ' ' << std::setw(8) << std::setfill('0') << std::hex << operands_[i];
85   }
86   os.copyfmt(saved_state);
87 
88   if (source_info_.is_valid()) {
89     os << ' ' << source_info_;
90   }
91   os << '\n';
92 #else
93   os << static_cast<const void*>(this);
94 #endif  // DEBUG
95 }
96 
Transform(Bytecode new_bytecode,uint32_t extra_operand)97 void BytecodeNode::Transform(Bytecode new_bytecode, uint32_t extra_operand) {
98   DCHECK_EQ(Bytecodes::NumberOfOperands(new_bytecode),
99             Bytecodes::NumberOfOperands(bytecode()) + 1);
100   DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 1 ||
101          Bytecodes::GetOperandType(new_bytecode, 0) ==
102              Bytecodes::GetOperandType(bytecode(), 0));
103   DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 2 ||
104          Bytecodes::GetOperandType(new_bytecode, 1) ==
105              Bytecodes::GetOperandType(bytecode(), 1));
106   DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 3 ||
107          Bytecodes::GetOperandType(new_bytecode, 2) ==
108              Bytecodes::GetOperandType(bytecode(), 2));
109   DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 4);
110   operands_[operand_count()] = extra_operand;
111   bytecode_ = new_bytecode;
112 }
113 
operator ==(const BytecodeNode & other) const114 bool BytecodeNode::operator==(const BytecodeNode& other) const {
115   if (this == &other) {
116     return true;
117   } else if (this->bytecode() != other.bytecode() ||
118              this->source_info() != other.source_info()) {
119     return false;
120   } else {
121     for (int i = 0; i < this->operand_count(); ++i) {
122       if (this->operand(i) != other.operand(i)) {
123         return false;
124       }
125     }
126   }
127   return true;
128 }
129 
operator <<(std::ostream & os,const BytecodeSourceInfo & info)130 std::ostream& operator<<(std::ostream& os, const BytecodeSourceInfo& info) {
131   if (info.is_valid()) {
132     char description = info.is_statement() ? 'S' : 'E';
133     os << info.source_position() << ' ' << description << '>';
134   }
135   return os;
136 }
137 
operator <<(std::ostream & os,const BytecodeNode & node)138 std::ostream& operator<<(std::ostream& os, const BytecodeNode& node) {
139   node.Print(os);
140   return os;
141 }
142 
143 }  // namespace interpreter
144 }  // namespace internal
145 }  // namespace v8
146