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