| 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 |