Index: src/interpreter/bytecode-array-iterator.cc |
diff --git a/src/interpreter/bytecode-array-iterator.cc b/src/interpreter/bytecode-array-iterator.cc |
index 0fea985efee2911cb141fdc4857e2d021d42a407..b7a6dcca39c9f383592b269c45a954efba4a67fd 100644 |
--- a/src/interpreter/bytecode-array-iterator.cc |
+++ b/src/interpreter/bytecode-array-iterator.cc |
@@ -12,31 +12,44 @@ namespace interpreter { |
BytecodeArrayIterator::BytecodeArrayIterator( |
Handle<BytecodeArray> bytecode_array) |
- : bytecode_array_(bytecode_array), bytecode_offset_(0) {} |
- |
+ : bytecode_array_(bytecode_array), |
+ bytecode_offset_(0), |
+ operand_scale_(1), |
+ prefix_offset_(0) { |
+ update_operand_scale(); |
+} |
void BytecodeArrayIterator::Advance() { |
- bytecode_offset_ += Bytecodes::Size(current_bytecode()); |
+ bytecode_offset_ += current_bytecode_size(); |
+ update_operand_scale(); |
} |
+void BytecodeArrayIterator::update_operand_scale() { |
+ if (!done()) { |
+ uint8_t current_byte = bytecode_array()->get(bytecode_offset_); |
+ Bytecode current_bytecode = Bytecodes::FromByte(current_byte); |
+ operand_scale_ = Bytecodes::GetPrefixBytecodeScale(current_bytecode); |
+ prefix_offset_ = current_operand_scale() > 1 ? 1 : 0; |
+ } |
+} |
bool BytecodeArrayIterator::done() const { |
return bytecode_offset_ >= bytecode_array()->length(); |
} |
- |
Bytecode BytecodeArrayIterator::current_bytecode() const { |
DCHECK(!done()); |
- uint8_t current_byte = bytecode_array()->get(bytecode_offset_); |
- return interpreter::Bytecodes::FromByte(current_byte); |
+ uint8_t current_byte = |
+ bytecode_array()->get(bytecode_offset_ + current_prefix_offset()); |
+ Bytecode current_bytecode = Bytecodes::FromByte(current_byte); |
+ return current_bytecode; |
} |
- |
int BytecodeArrayIterator::current_bytecode_size() const { |
- return Bytecodes::Size(current_bytecode()); |
+ return current_prefix_offset() + |
+ Bytecodes::Size(current_bytecode(), current_operand_scale()); |
} |
- |
uint32_t BytecodeArrayIterator::GetRawOperand(int operand_index, |
OperandType operand_type) const { |
DCHECK_GE(operand_index, 0); |
@@ -45,57 +58,89 @@ uint32_t BytecodeArrayIterator::GetRawOperand(int operand_index, |
Bytecodes::GetOperandType(current_bytecode(), operand_index)); |
uint8_t* operand_start = |
bytecode_array()->GetFirstBytecodeAddress() + bytecode_offset_ + |
- Bytecodes::GetOperandOffset(current_bytecode(), operand_index); |
- switch (Bytecodes::SizeOfOperand(operand_type)) { |
+ current_prefix_offset() + |
+ Bytecodes::GetOperandOffset(current_bytecode(), operand_index, |
+ current_operand_scale()); |
+ switch (Bytecodes::SizeOfOperand(operand_type, current_operand_scale())) { |
case OperandSize::kByte: |
return static_cast<uint32_t>(*operand_start); |
case OperandSize::kShort: |
return ReadUnalignedUInt16(operand_start); |
+ case OperandSize::kQuad: |
+ return ReadUnalignedUInt32(operand_start); |
case OperandSize::kNone: |
UNREACHABLE(); |
} |
return 0; |
} |
+int32_t BytecodeArrayIterator::GetRawOperandSigned( |
+ int operand_index, OperandType operand_type) const { |
+ DCHECK_GE(operand_index, 0); |
+ DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(current_bytecode())); |
+ DCHECK_EQ(operand_type, |
+ Bytecodes::GetOperandType(current_bytecode(), operand_index)); |
+ uint8_t* operand_start = |
+ bytecode_array()->GetFirstBytecodeAddress() + bytecode_offset_ + |
+ current_prefix_offset() + |
+ Bytecodes::GetOperandOffset(current_bytecode(), operand_index, |
+ current_operand_scale()); |
+ switch (Bytecodes::SizeOfOperand(operand_type, current_operand_scale())) { |
+ case OperandSize::kByte: |
+ return static_cast<int8_t>(*operand_start); |
+ case OperandSize::kShort: |
+ return static_cast<int16_t>(ReadUnalignedUInt16(operand_start)); |
+ case OperandSize::kQuad: |
+ return static_cast<int32_t>(ReadUnalignedUInt32(operand_start)); |
+ case OperandSize::kNone: |
+ UNREACHABLE(); |
+ } |
+ return 0; |
+} |
-int8_t BytecodeArrayIterator::GetImmediateOperand(int operand_index) const { |
- uint32_t operand = GetRawOperand(operand_index, OperandType::kImm8); |
- return static_cast<int8_t>(operand); |
+uint32_t BytecodeArrayIterator::GetFlagOperand(int operand_index) const { |
+ DCHECK(Bytecodes::GetOperandType(current_bytecode(), operand_index) == |
+ OperandType::kFlag8); |
+ return GetRawOperand(operand_index, OperandType::kFlag8); |
} |
-int BytecodeArrayIterator::GetRegisterCountOperand(int operand_index) const { |
- OperandSize size = |
- Bytecodes::GetOperandSize(current_bytecode(), operand_index); |
- OperandType type = (size == OperandSize::kByte) ? OperandType::kRegCount8 |
- : OperandType::kRegCount16; |
- uint32_t operand = GetRawOperand(operand_index, type); |
- return static_cast<int>(operand); |
+int32_t BytecodeArrayIterator::GetImmediateOperand(int operand_index) const { |
+ DCHECK(Bytecodes::GetOperandType(current_bytecode(), operand_index) == |
+ OperandType::kImm); |
+ return GetRawOperandSigned(operand_index, OperandType::kImm); |
} |
+uint32_t BytecodeArrayIterator::GetRegisterCountOperand( |
+ int operand_index) const { |
+ DCHECK(Bytecodes::GetOperandType(current_bytecode(), operand_index) == |
+ OperandType::kRegCount); |
+ return GetRawOperand(operand_index, OperandType::kRegCount); |
+} |
-int BytecodeArrayIterator::GetIndexOperand(int operand_index) const { |
+uint32_t BytecodeArrayIterator::GetIndexOperand(int operand_index) const { |
OperandType operand_type = |
Bytecodes::GetOperandType(current_bytecode(), operand_index); |
- DCHECK(operand_type == OperandType::kIdx8 || |
- operand_type == OperandType::kIdx16); |
- uint32_t operand = GetRawOperand(operand_index, operand_type); |
- return static_cast<int>(operand); |
+ DCHECK(operand_type == OperandType::kIdx); |
+ return GetRawOperand(operand_index, operand_type); |
} |
- |
Register BytecodeArrayIterator::GetRegisterOperand(int operand_index) const { |
OperandType operand_type = |
Bytecodes::GetOperandType(current_bytecode(), operand_index); |
DCHECK(Bytecodes::IsRegisterOperandType(operand_type)); |
uint32_t operand = GetRawOperand(operand_index, operand_type); |
Register reg; |
- switch (Bytecodes::GetOperandSize(current_bytecode(), operand_index)) { |
+ switch (Bytecodes::GetOperandSize(current_bytecode(), operand_index, |
+ current_operand_scale())) { |
case OperandSize::kByte: |
reg = Register::FromOperand(static_cast<uint8_t>(operand)); |
break; |
case OperandSize::kShort: |
reg = Register::FromWideOperand(static_cast<uint16_t>(operand)); |
break; |
+ case OperandSize::kQuad: |
+ reg = Register::FromRawOperand(operand); |
+ break; |
case OperandSize::kNone: |
UNREACHABLE(); |
reg = Register::invalid_value(); |
@@ -116,13 +161,10 @@ int BytecodeArrayIterator::GetRegisterOperandRange(int operand_index) const { |
Bytecodes::GetOperandType(current_bytecode(), operand_index); |
DCHECK(Bytecodes::IsRegisterOperandType(operand_type)); |
switch (operand_type) { |
- case OperandType::kRegPair8: |
- case OperandType::kRegPair16: |
- case OperandType::kRegOutPair8: |
- case OperandType::kRegOutPair16: |
+ case OperandType::kRegPair: |
+ case OperandType::kRegOutPair: |
return 2; |
- case OperandType::kRegOutTriple8: |
- case OperandType::kRegOutTriple16: |
+ case OperandType::kRegOutTriple: |
return 3; |
default: { |
if (operand_index + 1 != |
@@ -138,6 +180,13 @@ int BytecodeArrayIterator::GetRegisterOperandRange(int operand_index) const { |
} |
} |
+uint32_t BytecodeArrayIterator::GetRuntimeIdOperand(int operand_index) const { |
+ OperandType operand_type = |
+ Bytecodes::GetOperandType(current_bytecode(), operand_index); |
+ DCHECK(operand_type == OperandType::kRuntimeId); |
+ return GetRawOperand(operand_index, operand_type); |
+} |
+ |
Handle<Object> BytecodeArrayIterator::GetConstantForIndexOperand( |
int operand_index) const { |
return FixedArray::get(bytecode_array()->constant_pool(), |
@@ -150,11 +199,10 @@ int BytecodeArrayIterator::GetJumpTargetOffset() const { |
Bytecode bytecode = current_bytecode(); |
if (interpreter::Bytecodes::IsJumpImmediate(bytecode)) { |
int relative_offset = GetImmediateOperand(0); |
- return current_offset() + relative_offset; |
- } else if (interpreter::Bytecodes::IsJumpConstant(bytecode) || |
- interpreter::Bytecodes::IsJumpConstantWide(bytecode)) { |
+ return current_offset() + relative_offset + current_prefix_offset(); |
+ } else if (interpreter::Bytecodes::IsJumpConstant(bytecode)) { |
Smi* smi = Smi::cast(*GetConstantForIndexOperand(0)); |
- return current_offset() + smi->value(); |
+ return current_offset() + smi->value() + current_prefix_offset(); |
} else { |
UNREACHABLE(); |
return kMinInt; |