11cb0ef41Sopenharmony_ci// Copyright 2015 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#include "src/interpreter/bytecode-array-iterator.h" 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci#include "src/interpreter/bytecode-decoder.h" 81cb0ef41Sopenharmony_ci#include "src/interpreter/interpreter-intrinsics.h" 91cb0ef41Sopenharmony_ci#include "src/objects/code-inl.h" 101cb0ef41Sopenharmony_ci#include "src/objects/feedback-vector.h" 111cb0ef41Sopenharmony_ci#include "src/objects/objects-inl.h" 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_cinamespace v8 { 141cb0ef41Sopenharmony_cinamespace internal { 151cb0ef41Sopenharmony_cinamespace interpreter { 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_ciBytecodeArrayIterator::BytecodeArrayIterator( 181cb0ef41Sopenharmony_ci Handle<BytecodeArray> bytecode_array, int initial_offset) 191cb0ef41Sopenharmony_ci : bytecode_array_(bytecode_array), 201cb0ef41Sopenharmony_ci start_(reinterpret_cast<uint8_t*>( 211cb0ef41Sopenharmony_ci bytecode_array_->GetFirstBytecodeAddress())), 221cb0ef41Sopenharmony_ci end_(start_ + bytecode_array_->length()), 231cb0ef41Sopenharmony_ci cursor_(start_ + initial_offset), 241cb0ef41Sopenharmony_ci operand_scale_(OperandScale::kSingle), 251cb0ef41Sopenharmony_ci prefix_size_(0), 261cb0ef41Sopenharmony_ci local_heap_(LocalHeap::Current() 271cb0ef41Sopenharmony_ci ? LocalHeap::Current() 281cb0ef41Sopenharmony_ci : Isolate::Current()->main_thread_local_heap()) { 291cb0ef41Sopenharmony_ci local_heap_->AddGCEpilogueCallback(UpdatePointersCallback, this); 301cb0ef41Sopenharmony_ci UpdateOperandScale(); 311cb0ef41Sopenharmony_ci} 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ciBytecodeArrayIterator::~BytecodeArrayIterator() { 341cb0ef41Sopenharmony_ci local_heap_->RemoveGCEpilogueCallback(UpdatePointersCallback, this); 351cb0ef41Sopenharmony_ci} 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_civoid BytecodeArrayIterator::SetOffset(int offset) { 381cb0ef41Sopenharmony_ci if (offset < 0) return; 391cb0ef41Sopenharmony_ci cursor_ = reinterpret_cast<uint8_t*>( 401cb0ef41Sopenharmony_ci bytecode_array()->GetFirstBytecodeAddress() + offset); 411cb0ef41Sopenharmony_ci UpdateOperandScale(); 421cb0ef41Sopenharmony_ci} 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_civoid BytecodeArrayIterator::ApplyDebugBreak() { 451cb0ef41Sopenharmony_ci // Get the raw bytecode from the bytecode array. This may give us a 461cb0ef41Sopenharmony_ci // scaling prefix, which we can patch with the matching debug-break 471cb0ef41Sopenharmony_ci // variant. 481cb0ef41Sopenharmony_ci uint8_t* cursor = cursor_ - prefix_size_; 491cb0ef41Sopenharmony_ci interpreter::Bytecode bytecode = interpreter::Bytecodes::FromByte(*cursor); 501cb0ef41Sopenharmony_ci if (interpreter::Bytecodes::IsDebugBreak(bytecode)) return; 511cb0ef41Sopenharmony_ci interpreter::Bytecode debugbreak = 521cb0ef41Sopenharmony_ci interpreter::Bytecodes::GetDebugBreak(bytecode); 531cb0ef41Sopenharmony_ci *cursor = interpreter::Bytecodes::ToByte(debugbreak); 541cb0ef41Sopenharmony_ci} 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ciuint32_t BytecodeArrayIterator::GetUnsignedOperand( 571cb0ef41Sopenharmony_ci int operand_index, OperandType operand_type) const { 581cb0ef41Sopenharmony_ci DCHECK_GE(operand_index, 0); 591cb0ef41Sopenharmony_ci DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(current_bytecode())); 601cb0ef41Sopenharmony_ci DCHECK_EQ(operand_type, 611cb0ef41Sopenharmony_ci Bytecodes::GetOperandType(current_bytecode(), operand_index)); 621cb0ef41Sopenharmony_ci DCHECK(Bytecodes::IsUnsignedOperandType(operand_type)); 631cb0ef41Sopenharmony_ci Address operand_start = 641cb0ef41Sopenharmony_ci reinterpret_cast<Address>(cursor_) + 651cb0ef41Sopenharmony_ci Bytecodes::GetOperandOffset(current_bytecode(), operand_index, 661cb0ef41Sopenharmony_ci current_operand_scale()); 671cb0ef41Sopenharmony_ci return BytecodeDecoder::DecodeUnsignedOperand(operand_start, operand_type, 681cb0ef41Sopenharmony_ci current_operand_scale()); 691cb0ef41Sopenharmony_ci} 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_ciint32_t BytecodeArrayIterator::GetSignedOperand( 721cb0ef41Sopenharmony_ci int operand_index, OperandType operand_type) const { 731cb0ef41Sopenharmony_ci DCHECK_GE(operand_index, 0); 741cb0ef41Sopenharmony_ci DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(current_bytecode())); 751cb0ef41Sopenharmony_ci DCHECK_EQ(operand_type, 761cb0ef41Sopenharmony_ci Bytecodes::GetOperandType(current_bytecode(), operand_index)); 771cb0ef41Sopenharmony_ci DCHECK(!Bytecodes::IsUnsignedOperandType(operand_type)); 781cb0ef41Sopenharmony_ci Address operand_start = 791cb0ef41Sopenharmony_ci reinterpret_cast<Address>(cursor_) + 801cb0ef41Sopenharmony_ci Bytecodes::GetOperandOffset(current_bytecode(), operand_index, 811cb0ef41Sopenharmony_ci current_operand_scale()); 821cb0ef41Sopenharmony_ci return BytecodeDecoder::DecodeSignedOperand(operand_start, operand_type, 831cb0ef41Sopenharmony_ci current_operand_scale()); 841cb0ef41Sopenharmony_ci} 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ciuint32_t BytecodeArrayIterator::GetFlagOperand(int operand_index) const { 871cb0ef41Sopenharmony_ci DCHECK_EQ(Bytecodes::GetOperandType(current_bytecode(), operand_index), 881cb0ef41Sopenharmony_ci OperandType::kFlag8); 891cb0ef41Sopenharmony_ci return GetUnsignedOperand(operand_index, OperandType::kFlag8); 901cb0ef41Sopenharmony_ci} 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_ciuint32_t BytecodeArrayIterator::GetUnsignedImmediateOperand( 931cb0ef41Sopenharmony_ci int operand_index) const { 941cb0ef41Sopenharmony_ci DCHECK_EQ(Bytecodes::GetOperandType(current_bytecode(), operand_index), 951cb0ef41Sopenharmony_ci OperandType::kUImm); 961cb0ef41Sopenharmony_ci return GetUnsignedOperand(operand_index, OperandType::kUImm); 971cb0ef41Sopenharmony_ci} 981cb0ef41Sopenharmony_ci 991cb0ef41Sopenharmony_ciint32_t BytecodeArrayIterator::GetImmediateOperand(int operand_index) const { 1001cb0ef41Sopenharmony_ci DCHECK_EQ(Bytecodes::GetOperandType(current_bytecode(), operand_index), 1011cb0ef41Sopenharmony_ci OperandType::kImm); 1021cb0ef41Sopenharmony_ci return GetSignedOperand(operand_index, OperandType::kImm); 1031cb0ef41Sopenharmony_ci} 1041cb0ef41Sopenharmony_ci 1051cb0ef41Sopenharmony_ciuint32_t BytecodeArrayIterator::GetRegisterCountOperand( 1061cb0ef41Sopenharmony_ci int operand_index) const { 1071cb0ef41Sopenharmony_ci DCHECK_EQ(Bytecodes::GetOperandType(current_bytecode(), operand_index), 1081cb0ef41Sopenharmony_ci OperandType::kRegCount); 1091cb0ef41Sopenharmony_ci return GetUnsignedOperand(operand_index, OperandType::kRegCount); 1101cb0ef41Sopenharmony_ci} 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_ciuint32_t BytecodeArrayIterator::GetIndexOperand(int operand_index) const { 1131cb0ef41Sopenharmony_ci OperandType operand_type = 1141cb0ef41Sopenharmony_ci Bytecodes::GetOperandType(current_bytecode(), operand_index); 1151cb0ef41Sopenharmony_ci DCHECK_EQ(operand_type, OperandType::kIdx); 1161cb0ef41Sopenharmony_ci return GetUnsignedOperand(operand_index, operand_type); 1171cb0ef41Sopenharmony_ci} 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ciFeedbackSlot BytecodeArrayIterator::GetSlotOperand(int operand_index) const { 1201cb0ef41Sopenharmony_ci int index = GetIndexOperand(operand_index); 1211cb0ef41Sopenharmony_ci return FeedbackVector::ToSlot(index); 1221cb0ef41Sopenharmony_ci} 1231cb0ef41Sopenharmony_ci 1241cb0ef41Sopenharmony_ciRegister BytecodeArrayIterator::GetReceiver() const { 1251cb0ef41Sopenharmony_ci return Register::FromParameterIndex(0); 1261cb0ef41Sopenharmony_ci} 1271cb0ef41Sopenharmony_ci 1281cb0ef41Sopenharmony_ciRegister BytecodeArrayIterator::GetParameter(int parameter_index) const { 1291cb0ef41Sopenharmony_ci DCHECK_GE(parameter_index, 0); 1301cb0ef41Sopenharmony_ci // The parameter indices are shifted by 1 (receiver is the 1311cb0ef41Sopenharmony_ci // first entry). 1321cb0ef41Sopenharmony_ci return Register::FromParameterIndex(parameter_index + 1); 1331cb0ef41Sopenharmony_ci} 1341cb0ef41Sopenharmony_ci 1351cb0ef41Sopenharmony_ciRegister BytecodeArrayIterator::GetRegisterOperand(int operand_index) const { 1361cb0ef41Sopenharmony_ci OperandType operand_type = 1371cb0ef41Sopenharmony_ci Bytecodes::GetOperandType(current_bytecode(), operand_index); 1381cb0ef41Sopenharmony_ci Address operand_start = 1391cb0ef41Sopenharmony_ci reinterpret_cast<Address>(cursor_) + 1401cb0ef41Sopenharmony_ci Bytecodes::GetOperandOffset(current_bytecode(), operand_index, 1411cb0ef41Sopenharmony_ci current_operand_scale()); 1421cb0ef41Sopenharmony_ci return BytecodeDecoder::DecodeRegisterOperand(operand_start, operand_type, 1431cb0ef41Sopenharmony_ci current_operand_scale()); 1441cb0ef41Sopenharmony_ci} 1451cb0ef41Sopenharmony_ci 1461cb0ef41Sopenharmony_cistd::pair<Register, Register> BytecodeArrayIterator::GetRegisterPairOperand( 1471cb0ef41Sopenharmony_ci int operand_index) const { 1481cb0ef41Sopenharmony_ci Register first = GetRegisterOperand(operand_index); 1491cb0ef41Sopenharmony_ci Register second(first.index() + 1); 1501cb0ef41Sopenharmony_ci return std::make_pair(first, second); 1511cb0ef41Sopenharmony_ci} 1521cb0ef41Sopenharmony_ci 1531cb0ef41Sopenharmony_ciRegisterList BytecodeArrayIterator::GetRegisterListOperand( 1541cb0ef41Sopenharmony_ci int operand_index) const { 1551cb0ef41Sopenharmony_ci Register first = GetRegisterOperand(operand_index); 1561cb0ef41Sopenharmony_ci uint32_t count = GetRegisterCountOperand(operand_index + 1); 1571cb0ef41Sopenharmony_ci return RegisterList(first.index(), count); 1581cb0ef41Sopenharmony_ci} 1591cb0ef41Sopenharmony_ci 1601cb0ef41Sopenharmony_ciint BytecodeArrayIterator::GetRegisterOperandRange(int operand_index) const { 1611cb0ef41Sopenharmony_ci DCHECK_LE(operand_index, Bytecodes::NumberOfOperands(current_bytecode())); 1621cb0ef41Sopenharmony_ci const OperandType* operand_types = 1631cb0ef41Sopenharmony_ci Bytecodes::GetOperandTypes(current_bytecode()); 1641cb0ef41Sopenharmony_ci OperandType operand_type = operand_types[operand_index]; 1651cb0ef41Sopenharmony_ci DCHECK(Bytecodes::IsRegisterOperandType(operand_type)); 1661cb0ef41Sopenharmony_ci if (operand_type == OperandType::kRegList || 1671cb0ef41Sopenharmony_ci operand_type == OperandType::kRegOutList) { 1681cb0ef41Sopenharmony_ci return GetRegisterCountOperand(operand_index + 1); 1691cb0ef41Sopenharmony_ci } else { 1701cb0ef41Sopenharmony_ci return Bytecodes::GetNumberOfRegistersRepresentedBy(operand_type); 1711cb0ef41Sopenharmony_ci } 1721cb0ef41Sopenharmony_ci} 1731cb0ef41Sopenharmony_ci 1741cb0ef41Sopenharmony_ciRuntime::FunctionId BytecodeArrayIterator::GetRuntimeIdOperand( 1751cb0ef41Sopenharmony_ci int operand_index) const { 1761cb0ef41Sopenharmony_ci OperandType operand_type = 1771cb0ef41Sopenharmony_ci Bytecodes::GetOperandType(current_bytecode(), operand_index); 1781cb0ef41Sopenharmony_ci DCHECK_EQ(operand_type, OperandType::kRuntimeId); 1791cb0ef41Sopenharmony_ci uint32_t raw_id = GetUnsignedOperand(operand_index, operand_type); 1801cb0ef41Sopenharmony_ci return static_cast<Runtime::FunctionId>(raw_id); 1811cb0ef41Sopenharmony_ci} 1821cb0ef41Sopenharmony_ci 1831cb0ef41Sopenharmony_ciuint32_t BytecodeArrayIterator::GetNativeContextIndexOperand( 1841cb0ef41Sopenharmony_ci int operand_index) const { 1851cb0ef41Sopenharmony_ci OperandType operand_type = 1861cb0ef41Sopenharmony_ci Bytecodes::GetOperandType(current_bytecode(), operand_index); 1871cb0ef41Sopenharmony_ci DCHECK_EQ(operand_type, OperandType::kNativeContextIndex); 1881cb0ef41Sopenharmony_ci return GetUnsignedOperand(operand_index, operand_type); 1891cb0ef41Sopenharmony_ci} 1901cb0ef41Sopenharmony_ci 1911cb0ef41Sopenharmony_ciRuntime::FunctionId BytecodeArrayIterator::GetIntrinsicIdOperand( 1921cb0ef41Sopenharmony_ci int operand_index) const { 1931cb0ef41Sopenharmony_ci OperandType operand_type = 1941cb0ef41Sopenharmony_ci Bytecodes::GetOperandType(current_bytecode(), operand_index); 1951cb0ef41Sopenharmony_ci DCHECK_EQ(operand_type, OperandType::kIntrinsicId); 1961cb0ef41Sopenharmony_ci uint32_t raw_id = GetUnsignedOperand(operand_index, operand_type); 1971cb0ef41Sopenharmony_ci return IntrinsicsHelper::ToRuntimeId( 1981cb0ef41Sopenharmony_ci static_cast<IntrinsicsHelper::IntrinsicId>(raw_id)); 1991cb0ef41Sopenharmony_ci} 2001cb0ef41Sopenharmony_ci 2011cb0ef41Sopenharmony_citemplate <typename IsolateT> 2021cb0ef41Sopenharmony_ciHandle<Object> BytecodeArrayIterator::GetConstantAtIndex( 2031cb0ef41Sopenharmony_ci int index, IsolateT* isolate) const { 2041cb0ef41Sopenharmony_ci return handle(bytecode_array()->constant_pool().get(index), isolate); 2051cb0ef41Sopenharmony_ci} 2061cb0ef41Sopenharmony_ci 2071cb0ef41Sopenharmony_cibool BytecodeArrayIterator::IsConstantAtIndexSmi(int index) const { 2081cb0ef41Sopenharmony_ci return bytecode_array()->constant_pool().get(index).IsSmi(); 2091cb0ef41Sopenharmony_ci} 2101cb0ef41Sopenharmony_ci 2111cb0ef41Sopenharmony_ciSmi BytecodeArrayIterator::GetConstantAtIndexAsSmi(int index) const { 2121cb0ef41Sopenharmony_ci return Smi::cast(bytecode_array()->constant_pool().get(index)); 2131cb0ef41Sopenharmony_ci} 2141cb0ef41Sopenharmony_ci 2151cb0ef41Sopenharmony_citemplate <typename IsolateT> 2161cb0ef41Sopenharmony_ciHandle<Object> BytecodeArrayIterator::GetConstantForIndexOperand( 2171cb0ef41Sopenharmony_ci int operand_index, IsolateT* isolate) const { 2181cb0ef41Sopenharmony_ci return GetConstantAtIndex(GetIndexOperand(operand_index), isolate); 2191cb0ef41Sopenharmony_ci} 2201cb0ef41Sopenharmony_ci 2211cb0ef41Sopenharmony_citemplate EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) 2221cb0ef41Sopenharmony_ci Handle<Object> BytecodeArrayIterator::GetConstantForIndexOperand( 2231cb0ef41Sopenharmony_ci int operand_index, Isolate* isolate) const; 2241cb0ef41Sopenharmony_citemplate Handle<Object> BytecodeArrayIterator::GetConstantForIndexOperand( 2251cb0ef41Sopenharmony_ci int operand_index, LocalIsolate* isolate) const; 2261cb0ef41Sopenharmony_ci 2271cb0ef41Sopenharmony_ciint BytecodeArrayIterator::GetRelativeJumpTargetOffset() const { 2281cb0ef41Sopenharmony_ci Bytecode bytecode = current_bytecode(); 2291cb0ef41Sopenharmony_ci if (interpreter::Bytecodes::IsJumpImmediate(bytecode)) { 2301cb0ef41Sopenharmony_ci int relative_offset = GetUnsignedImmediateOperand(0); 2311cb0ef41Sopenharmony_ci if (bytecode == Bytecode::kJumpLoop) { 2321cb0ef41Sopenharmony_ci relative_offset = -relative_offset; 2331cb0ef41Sopenharmony_ci } 2341cb0ef41Sopenharmony_ci return relative_offset; 2351cb0ef41Sopenharmony_ci } else if (interpreter::Bytecodes::IsJumpConstant(bytecode)) { 2361cb0ef41Sopenharmony_ci Smi smi = GetConstantAtIndexAsSmi(GetIndexOperand(0)); 2371cb0ef41Sopenharmony_ci return smi.value(); 2381cb0ef41Sopenharmony_ci } else { 2391cb0ef41Sopenharmony_ci UNREACHABLE(); 2401cb0ef41Sopenharmony_ci } 2411cb0ef41Sopenharmony_ci} 2421cb0ef41Sopenharmony_ci 2431cb0ef41Sopenharmony_ciint BytecodeArrayIterator::GetJumpTargetOffset() const { 2441cb0ef41Sopenharmony_ci return GetAbsoluteOffset(GetRelativeJumpTargetOffset()); 2451cb0ef41Sopenharmony_ci} 2461cb0ef41Sopenharmony_ci 2471cb0ef41Sopenharmony_ciJumpTableTargetOffsets BytecodeArrayIterator::GetJumpTableTargetOffsets() 2481cb0ef41Sopenharmony_ci const { 2491cb0ef41Sopenharmony_ci uint32_t table_start, table_size; 2501cb0ef41Sopenharmony_ci int32_t case_value_base; 2511cb0ef41Sopenharmony_ci if (current_bytecode() == Bytecode::kSwitchOnGeneratorState) { 2521cb0ef41Sopenharmony_ci table_start = GetIndexOperand(1); 2531cb0ef41Sopenharmony_ci table_size = GetUnsignedImmediateOperand(2); 2541cb0ef41Sopenharmony_ci case_value_base = 0; 2551cb0ef41Sopenharmony_ci } else { 2561cb0ef41Sopenharmony_ci DCHECK_EQ(current_bytecode(), Bytecode::kSwitchOnSmiNoFeedback); 2571cb0ef41Sopenharmony_ci table_start = GetIndexOperand(0); 2581cb0ef41Sopenharmony_ci table_size = GetUnsignedImmediateOperand(1); 2591cb0ef41Sopenharmony_ci case_value_base = GetImmediateOperand(2); 2601cb0ef41Sopenharmony_ci } 2611cb0ef41Sopenharmony_ci return JumpTableTargetOffsets(this, table_start, table_size, case_value_base); 2621cb0ef41Sopenharmony_ci} 2631cb0ef41Sopenharmony_ci 2641cb0ef41Sopenharmony_ciint BytecodeArrayIterator::GetAbsoluteOffset(int relative_offset) const { 2651cb0ef41Sopenharmony_ci return current_offset() + relative_offset + prefix_size_; 2661cb0ef41Sopenharmony_ci} 2671cb0ef41Sopenharmony_ci 2681cb0ef41Sopenharmony_cistd::ostream& BytecodeArrayIterator::PrintTo(std::ostream& os) const { 2691cb0ef41Sopenharmony_ci return BytecodeDecoder::Decode(os, cursor_ - prefix_size_); 2701cb0ef41Sopenharmony_ci} 2711cb0ef41Sopenharmony_ci 2721cb0ef41Sopenharmony_civoid BytecodeArrayIterator::UpdatePointers() { 2731cb0ef41Sopenharmony_ci DisallowGarbageCollection no_gc; 2741cb0ef41Sopenharmony_ci uint8_t* start = 2751cb0ef41Sopenharmony_ci reinterpret_cast<uint8_t*>(bytecode_array_->GetFirstBytecodeAddress()); 2761cb0ef41Sopenharmony_ci if (start != start_) { 2771cb0ef41Sopenharmony_ci start_ = start; 2781cb0ef41Sopenharmony_ci uint8_t* end = start + bytecode_array_->length(); 2791cb0ef41Sopenharmony_ci size_t distance_to_end = end_ - cursor_; 2801cb0ef41Sopenharmony_ci cursor_ = end - distance_to_end; 2811cb0ef41Sopenharmony_ci end_ = end; 2821cb0ef41Sopenharmony_ci } 2831cb0ef41Sopenharmony_ci} 2841cb0ef41Sopenharmony_ci 2851cb0ef41Sopenharmony_ciJumpTableTargetOffsets::JumpTableTargetOffsets( 2861cb0ef41Sopenharmony_ci const BytecodeArrayIterator* iterator, int table_start, int table_size, 2871cb0ef41Sopenharmony_ci int case_value_base) 2881cb0ef41Sopenharmony_ci : iterator_(iterator), 2891cb0ef41Sopenharmony_ci table_start_(table_start), 2901cb0ef41Sopenharmony_ci table_size_(table_size), 2911cb0ef41Sopenharmony_ci case_value_base_(case_value_base) {} 2921cb0ef41Sopenharmony_ci 2931cb0ef41Sopenharmony_ciJumpTableTargetOffsets::iterator JumpTableTargetOffsets::begin() const { 2941cb0ef41Sopenharmony_ci return iterator(case_value_base_, table_start_, table_start_ + table_size_, 2951cb0ef41Sopenharmony_ci iterator_); 2961cb0ef41Sopenharmony_ci} 2971cb0ef41Sopenharmony_ciJumpTableTargetOffsets::iterator JumpTableTargetOffsets::end() const { 2981cb0ef41Sopenharmony_ci return iterator(case_value_base_ + table_size_, table_start_ + table_size_, 2991cb0ef41Sopenharmony_ci table_start_ + table_size_, iterator_); 3001cb0ef41Sopenharmony_ci} 3011cb0ef41Sopenharmony_ciint JumpTableTargetOffsets::size() const { 3021cb0ef41Sopenharmony_ci int ret = 0; 3031cb0ef41Sopenharmony_ci // TODO(leszeks): Is there a more efficient way of doing this than iterating? 3041cb0ef41Sopenharmony_ci for (JumpTableTargetOffset entry : *this) { 3051cb0ef41Sopenharmony_ci USE(entry); 3061cb0ef41Sopenharmony_ci ret++; 3071cb0ef41Sopenharmony_ci } 3081cb0ef41Sopenharmony_ci return ret; 3091cb0ef41Sopenharmony_ci} 3101cb0ef41Sopenharmony_ci 3111cb0ef41Sopenharmony_ciJumpTableTargetOffsets::iterator::iterator( 3121cb0ef41Sopenharmony_ci int case_value, int table_offset, int table_end, 3131cb0ef41Sopenharmony_ci const BytecodeArrayIterator* iterator) 3141cb0ef41Sopenharmony_ci : iterator_(iterator), 3151cb0ef41Sopenharmony_ci current_(Smi::zero()), 3161cb0ef41Sopenharmony_ci index_(case_value), 3171cb0ef41Sopenharmony_ci table_offset_(table_offset), 3181cb0ef41Sopenharmony_ci table_end_(table_end) { 3191cb0ef41Sopenharmony_ci UpdateAndAdvanceToValid(); 3201cb0ef41Sopenharmony_ci} 3211cb0ef41Sopenharmony_ci 3221cb0ef41Sopenharmony_ciJumpTableTargetOffset JumpTableTargetOffsets::iterator::operator*() { 3231cb0ef41Sopenharmony_ci DCHECK_LT(table_offset_, table_end_); 3241cb0ef41Sopenharmony_ci return {index_, iterator_->GetAbsoluteOffset(Smi::ToInt(current_))}; 3251cb0ef41Sopenharmony_ci} 3261cb0ef41Sopenharmony_ci 3271cb0ef41Sopenharmony_ciJumpTableTargetOffsets::iterator& 3281cb0ef41Sopenharmony_ciJumpTableTargetOffsets::iterator::operator++() { 3291cb0ef41Sopenharmony_ci DCHECK_LT(table_offset_, table_end_); 3301cb0ef41Sopenharmony_ci ++table_offset_; 3311cb0ef41Sopenharmony_ci ++index_; 3321cb0ef41Sopenharmony_ci UpdateAndAdvanceToValid(); 3331cb0ef41Sopenharmony_ci return *this; 3341cb0ef41Sopenharmony_ci} 3351cb0ef41Sopenharmony_ci 3361cb0ef41Sopenharmony_cibool JumpTableTargetOffsets::iterator::operator!=( 3371cb0ef41Sopenharmony_ci const JumpTableTargetOffsets::iterator& other) { 3381cb0ef41Sopenharmony_ci DCHECK_EQ(iterator_, other.iterator_); 3391cb0ef41Sopenharmony_ci DCHECK_EQ(table_end_, other.table_end_); 3401cb0ef41Sopenharmony_ci DCHECK_EQ(index_ - other.index_, table_offset_ - other.table_offset_); 3411cb0ef41Sopenharmony_ci return index_ != other.index_; 3421cb0ef41Sopenharmony_ci} 3431cb0ef41Sopenharmony_ci 3441cb0ef41Sopenharmony_civoid JumpTableTargetOffsets::iterator::UpdateAndAdvanceToValid() { 3451cb0ef41Sopenharmony_ci while (table_offset_ < table_end_ && 3461cb0ef41Sopenharmony_ci !iterator_->IsConstantAtIndexSmi(table_offset_)) { 3471cb0ef41Sopenharmony_ci ++table_offset_; 3481cb0ef41Sopenharmony_ci ++index_; 3491cb0ef41Sopenharmony_ci } 3501cb0ef41Sopenharmony_ci 3511cb0ef41Sopenharmony_ci // Make sure we haven't reached the end of the table with a hole in current. 3521cb0ef41Sopenharmony_ci if (table_offset_ < table_end_) { 3531cb0ef41Sopenharmony_ci DCHECK(iterator_->IsConstantAtIndexSmi(table_offset_)); 3541cb0ef41Sopenharmony_ci current_ = iterator_->GetConstantAtIndexAsSmi(table_offset_); 3551cb0ef41Sopenharmony_ci } 3561cb0ef41Sopenharmony_ci} 3571cb0ef41Sopenharmony_ci 3581cb0ef41Sopenharmony_ci} // namespace interpreter 3591cb0ef41Sopenharmony_ci} // namespace internal 3601cb0ef41Sopenharmony_ci} // namespace v8 361