OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/interpreter/bytecode-array-iterator.h" | 5 #include "src/interpreter/bytecode-array-iterator.h" |
6 | |
7 #include "src/interpreter/bytecode-decoder.h" | |
8 #include "src/interpreter/interpreter-intrinsics.h" | |
9 #include "src/objects-inl.h" | 6 #include "src/objects-inl.h" |
10 | 7 |
11 namespace v8 { | 8 namespace v8 { |
12 namespace internal { | 9 namespace internal { |
13 namespace interpreter { | 10 namespace interpreter { |
14 | 11 |
15 BytecodeArrayIterator::BytecodeArrayIterator( | 12 BytecodeArrayIterator::BytecodeArrayIterator( |
16 Handle<BytecodeArray> bytecode_array) | 13 Handle<BytecodeArray> bytecode_array) |
17 : bytecode_array_(bytecode_array), | 14 : BytecodeArrayAccessor(bytecode_array, 0) {} |
18 bytecode_offset_(0), | |
19 operand_scale_(OperandScale::kSingle), | |
20 prefix_offset_(0) { | |
21 UpdateOperandScale(); | |
22 } | |
23 | 15 |
24 void BytecodeArrayIterator::Advance() { | 16 void BytecodeArrayIterator::Advance() { |
25 bytecode_offset_ += current_bytecode_size(); | 17 SetOffset(current_offset() + current_bytecode_size()); |
26 UpdateOperandScale(); | |
27 } | |
28 | |
29 void BytecodeArrayIterator::UpdateOperandScale() { | |
30 if (!done()) { | |
31 uint8_t current_byte = bytecode_array()->get(bytecode_offset_); | |
32 Bytecode current_bytecode = Bytecodes::FromByte(current_byte); | |
33 if (Bytecodes::IsPrefixScalingBytecode(current_bytecode)) { | |
34 operand_scale_ = | |
35 Bytecodes::PrefixBytecodeToOperandScale(current_bytecode); | |
36 prefix_offset_ = 1; | |
37 } else { | |
38 operand_scale_ = OperandScale::kSingle; | |
39 prefix_offset_ = 0; | |
40 } | |
41 } | |
42 } | 18 } |
43 | 19 |
44 bool BytecodeArrayIterator::done() const { | 20 bool BytecodeArrayIterator::done() const { |
45 return bytecode_offset_ >= bytecode_array()->length(); | 21 return current_offset() >= bytecode_array()->length(); |
46 } | |
47 | |
48 Bytecode BytecodeArrayIterator::current_bytecode() const { | |
49 DCHECK(!done()); | |
50 uint8_t current_byte = | |
51 bytecode_array()->get(bytecode_offset_ + current_prefix_offset()); | |
52 Bytecode current_bytecode = Bytecodes::FromByte(current_byte); | |
53 DCHECK(!Bytecodes::IsPrefixScalingBytecode(current_bytecode)); | |
54 return current_bytecode; | |
55 } | |
56 | |
57 int BytecodeArrayIterator::current_bytecode_size() const { | |
58 return current_prefix_offset() + | |
59 Bytecodes::Size(current_bytecode(), current_operand_scale()); | |
60 } | |
61 | |
62 uint32_t BytecodeArrayIterator::GetUnsignedOperand( | |
63 int operand_index, OperandType operand_type) const { | |
64 DCHECK_GE(operand_index, 0); | |
65 DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(current_bytecode())); | |
66 DCHECK_EQ(operand_type, | |
67 Bytecodes::GetOperandType(current_bytecode(), operand_index)); | |
68 DCHECK(Bytecodes::IsUnsignedOperandType(operand_type)); | |
69 const uint8_t* operand_start = | |
70 bytecode_array()->GetFirstBytecodeAddress() + bytecode_offset_ + | |
71 current_prefix_offset() + | |
72 Bytecodes::GetOperandOffset(current_bytecode(), operand_index, | |
73 current_operand_scale()); | |
74 return BytecodeDecoder::DecodeUnsignedOperand(operand_start, operand_type, | |
75 current_operand_scale()); | |
76 } | |
77 | |
78 int32_t BytecodeArrayIterator::GetSignedOperand( | |
79 int operand_index, OperandType operand_type) const { | |
80 DCHECK_GE(operand_index, 0); | |
81 DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(current_bytecode())); | |
82 DCHECK_EQ(operand_type, | |
83 Bytecodes::GetOperandType(current_bytecode(), operand_index)); | |
84 DCHECK(!Bytecodes::IsUnsignedOperandType(operand_type)); | |
85 const uint8_t* operand_start = | |
86 bytecode_array()->GetFirstBytecodeAddress() + bytecode_offset_ + | |
87 current_prefix_offset() + | |
88 Bytecodes::GetOperandOffset(current_bytecode(), operand_index, | |
89 current_operand_scale()); | |
90 return BytecodeDecoder::DecodeSignedOperand(operand_start, operand_type, | |
91 current_operand_scale()); | |
92 } | |
93 | |
94 uint32_t BytecodeArrayIterator::GetFlagOperand(int operand_index) const { | |
95 DCHECK_EQ(Bytecodes::GetOperandType(current_bytecode(), operand_index), | |
96 OperandType::kFlag8); | |
97 return GetUnsignedOperand(operand_index, OperandType::kFlag8); | |
98 } | |
99 | |
100 uint32_t BytecodeArrayIterator::GetUnsignedImmediateOperand( | |
101 int operand_index) const { | |
102 DCHECK_EQ(Bytecodes::GetOperandType(current_bytecode(), operand_index), | |
103 OperandType::kUImm); | |
104 return GetUnsignedOperand(operand_index, OperandType::kUImm); | |
105 } | |
106 | |
107 int32_t BytecodeArrayIterator::GetImmediateOperand(int operand_index) const { | |
108 DCHECK_EQ(Bytecodes::GetOperandType(current_bytecode(), operand_index), | |
109 OperandType::kImm); | |
110 return GetSignedOperand(operand_index, OperandType::kImm); | |
111 } | |
112 | |
113 uint32_t BytecodeArrayIterator::GetRegisterCountOperand( | |
114 int operand_index) const { | |
115 DCHECK_EQ(Bytecodes::GetOperandType(current_bytecode(), operand_index), | |
116 OperandType::kRegCount); | |
117 return GetUnsignedOperand(operand_index, OperandType::kRegCount); | |
118 } | |
119 | |
120 uint32_t BytecodeArrayIterator::GetIndexOperand(int operand_index) const { | |
121 OperandType operand_type = | |
122 Bytecodes::GetOperandType(current_bytecode(), operand_index); | |
123 DCHECK_EQ(operand_type, OperandType::kIdx); | |
124 return GetUnsignedOperand(operand_index, operand_type); | |
125 } | |
126 | |
127 Register BytecodeArrayIterator::GetRegisterOperand(int operand_index) const { | |
128 OperandType operand_type = | |
129 Bytecodes::GetOperandType(current_bytecode(), operand_index); | |
130 const uint8_t* operand_start = | |
131 bytecode_array()->GetFirstBytecodeAddress() + bytecode_offset_ + | |
132 current_prefix_offset() + | |
133 Bytecodes::GetOperandOffset(current_bytecode(), operand_index, | |
134 current_operand_scale()); | |
135 return BytecodeDecoder::DecodeRegisterOperand(operand_start, operand_type, | |
136 current_operand_scale()); | |
137 } | |
138 | |
139 int BytecodeArrayIterator::GetRegisterOperandRange(int operand_index) const { | |
140 DCHECK_LE(operand_index, Bytecodes::NumberOfOperands(current_bytecode())); | |
141 const OperandType* operand_types = | |
142 Bytecodes::GetOperandTypes(current_bytecode()); | |
143 OperandType operand_type = operand_types[operand_index]; | |
144 DCHECK(Bytecodes::IsRegisterOperandType(operand_type)); | |
145 if (operand_type == OperandType::kRegList) { | |
146 return GetRegisterCountOperand(operand_index + 1); | |
147 } else { | |
148 return Bytecodes::GetNumberOfRegistersRepresentedBy(operand_type); | |
149 } | |
150 } | |
151 | |
152 Runtime::FunctionId BytecodeArrayIterator::GetRuntimeIdOperand( | |
153 int operand_index) const { | |
154 OperandType operand_type = | |
155 Bytecodes::GetOperandType(current_bytecode(), operand_index); | |
156 DCHECK(operand_type == OperandType::kRuntimeId); | |
157 uint32_t raw_id = GetUnsignedOperand(operand_index, operand_type); | |
158 return static_cast<Runtime::FunctionId>(raw_id); | |
159 } | |
160 | |
161 Runtime::FunctionId BytecodeArrayIterator::GetIntrinsicIdOperand( | |
162 int operand_index) const { | |
163 OperandType operand_type = | |
164 Bytecodes::GetOperandType(current_bytecode(), operand_index); | |
165 DCHECK(operand_type == OperandType::kIntrinsicId); | |
166 uint32_t raw_id = GetUnsignedOperand(operand_index, operand_type); | |
167 return IntrinsicsHelper::ToRuntimeId( | |
168 static_cast<IntrinsicsHelper::IntrinsicId>(raw_id)); | |
169 } | |
170 | |
171 Handle<Object> BytecodeArrayIterator::GetConstantForIndexOperand( | |
172 int operand_index) const { | |
173 return FixedArray::get(bytecode_array()->constant_pool(), | |
174 GetIndexOperand(operand_index), | |
175 bytecode_array()->GetIsolate()); | |
176 } | |
177 | |
178 | |
179 int BytecodeArrayIterator::GetJumpTargetOffset() const { | |
180 Bytecode bytecode = current_bytecode(); | |
181 if (interpreter::Bytecodes::IsJumpImmediate(bytecode)) { | |
182 int relative_offset = GetImmediateOperand(0); | |
183 return current_offset() + relative_offset + current_prefix_offset(); | |
184 } else if (interpreter::Bytecodes::IsJumpConstant(bytecode)) { | |
185 Smi* smi = Smi::cast(*GetConstantForIndexOperand(0)); | |
186 return current_offset() + smi->value() + current_prefix_offset(); | |
187 } else { | |
188 UNREACHABLE(); | |
189 return kMinInt; | |
190 } | |
191 } | 22 } |
192 | 23 |
193 } // namespace interpreter | 24 } // namespace interpreter |
194 } // namespace internal | 25 } // namespace internal |
195 } // namespace v8 | 26 } // namespace v8 |
OLD | NEW |