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