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-array-iterator.h" 6 7 #include "src/objects-inl.h" 8 9 namespace v8 { 10 namespace internal { 11 namespace interpreter { 12 13 BytecodeArrayIterator::BytecodeArrayIterator( 14 Handle<BytecodeArray> bytecode_array) 15 : bytecode_array_(bytecode_array), bytecode_offset_(0) {} 16 17 18 void BytecodeArrayIterator::Advance() { 19 bytecode_offset_ += Bytecodes::Size(current_bytecode()); 20 } 21 22 23 bool BytecodeArrayIterator::done() const { 24 return bytecode_offset_ >= bytecode_array()->length(); 25 } 26 27 28 Bytecode BytecodeArrayIterator::current_bytecode() const { 29 DCHECK(!done()); 30 uint8_t current_byte = bytecode_array()->get(bytecode_offset_); 31 return interpreter::Bytecodes::FromByte(current_byte); 32 } 33 34 35 int BytecodeArrayIterator::current_bytecode_size() const { 36 return Bytecodes::Size(current_bytecode()); 37 } 38 39 40 uint32_t BytecodeArrayIterator::GetRawOperand(int operand_index, 41 OperandType operand_type) const { 42 DCHECK_GE(operand_index, 0); 43 DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(current_bytecode())); 44 DCHECK_EQ(operand_type, 45 Bytecodes::GetOperandType(current_bytecode(), operand_index)); 46 uint8_t* operand_start = 47 bytecode_array()->GetFirstBytecodeAddress() + bytecode_offset_ + 48 Bytecodes::GetOperandOffset(current_bytecode(), operand_index); 49 switch (Bytecodes::SizeOfOperand(operand_type)) { 50 default: 51 case OperandSize::kNone: 52 UNREACHABLE(); 53 case OperandSize::kByte: 54 return static_cast<uint32_t>(*operand_start); 55 case OperandSize::kShort: 56 return ReadUnalignedUInt16(operand_start); 57 } 58 } 59 60 61 int8_t BytecodeArrayIterator::GetImmediateOperand(int operand_index) const { 62 uint32_t operand = GetRawOperand(operand_index, OperandType::kImm8); 63 return static_cast<int8_t>(operand); 64 } 65 66 67 int BytecodeArrayIterator::GetCountOperand(int operand_index) const { 68 OperandSize size = 69 Bytecodes::GetOperandSize(current_bytecode(), operand_index); 70 OperandType type = (size == OperandSize::kByte) ? OperandType::kCount8 71 : OperandType::kCount16; 72 uint32_t operand = GetRawOperand(operand_index, type); 73 return static_cast<int>(operand); 74 } 75 76 77 int BytecodeArrayIterator::GetIndexOperand(int operand_index) const { 78 OperandType operand_type = 79 Bytecodes::GetOperandType(current_bytecode(), operand_index); 80 DCHECK(operand_type == OperandType::kIdx8 || 81 operand_type == OperandType::kIdx16); 82 uint32_t operand = GetRawOperand(operand_index, operand_type); 83 return static_cast<int>(operand); 84 } 85 86 87 Register BytecodeArrayIterator::GetRegisterOperand(int operand_index) const { 88 OperandType operand_type = 89 Bytecodes::GetOperandType(current_bytecode(), operand_index); 90 DCHECK(operand_type == OperandType::kReg8 || 91 operand_type == OperandType::kRegPair8 || 92 operand_type == OperandType::kMaybeReg8 || 93 operand_type == OperandType::kReg16); 94 uint32_t operand = GetRawOperand(operand_index, operand_type); 95 return Register::FromOperand(operand); 96 } 97 98 99 Handle<Object> BytecodeArrayIterator::GetConstantForIndexOperand( 100 int operand_index) const { 101 Handle<FixedArray> constants = handle(bytecode_array()->constant_pool()); 102 return FixedArray::get(constants, GetIndexOperand(operand_index)); 103 } 104 105 106 int BytecodeArrayIterator::GetJumpTargetOffset() const { 107 Bytecode bytecode = current_bytecode(); 108 if (interpreter::Bytecodes::IsJumpImmediate(bytecode)) { 109 int relative_offset = GetImmediateOperand(0); 110 return current_offset() + relative_offset; 111 } else if (interpreter::Bytecodes::IsJumpConstant(bytecode) || 112 interpreter::Bytecodes::IsJumpConstantWide(bytecode)) { 113 Smi* smi = Smi::cast(*GetConstantForIndexOperand(0)); 114 return current_offset() + smi->value(); 115 } else { 116 UNREACHABLE(); 117 return kMinInt; 118 } 119 } 120 121 } // namespace interpreter 122 } // namespace internal 123 } // namespace v8 124