11cb0ef41Sopenharmony_ci// Copyright 2016 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#ifndef V8_INTERPRETER_BYTECODE_ARRAY_ITERATOR_H_ 61cb0ef41Sopenharmony_ci#define V8_INTERPRETER_BYTECODE_ARRAY_ITERATOR_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include <memory> 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci#include "src/base/optional.h" 111cb0ef41Sopenharmony_ci#include "src/common/globals.h" 121cb0ef41Sopenharmony_ci#include "src/handles/handles.h" 131cb0ef41Sopenharmony_ci#include "src/interpreter/bytecode-register.h" 141cb0ef41Sopenharmony_ci#include "src/interpreter/bytecodes.h" 151cb0ef41Sopenharmony_ci#include "src/objects/objects.h" 161cb0ef41Sopenharmony_ci#include "src/objects/smi.h" 171cb0ef41Sopenharmony_ci#include "src/runtime/runtime.h" 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_cinamespace v8 { 201cb0ef41Sopenharmony_cinamespace internal { 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ciclass BytecodeArray; 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_cinamespace interpreter { 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ciclass BytecodeArrayIterator; 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_cistruct V8_EXPORT_PRIVATE JumpTableTargetOffset { 291cb0ef41Sopenharmony_ci int case_value; 301cb0ef41Sopenharmony_ci int target_offset; 311cb0ef41Sopenharmony_ci}; 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE JumpTableTargetOffsets final { 341cb0ef41Sopenharmony_ci public: 351cb0ef41Sopenharmony_ci // Minimal iterator implementation for use in ranged-for. 361cb0ef41Sopenharmony_ci class V8_EXPORT_PRIVATE iterator final { 371cb0ef41Sopenharmony_ci public: 381cb0ef41Sopenharmony_ci iterator(int case_value, int table_offset, int table_end, 391cb0ef41Sopenharmony_ci const BytecodeArrayIterator* iterator); 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ci JumpTableTargetOffset operator*(); 421cb0ef41Sopenharmony_ci iterator& operator++(); 431cb0ef41Sopenharmony_ci bool operator!=(const iterator& other); 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci private: 461cb0ef41Sopenharmony_ci void UpdateAndAdvanceToValid(); 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_ci const BytecodeArrayIterator* iterator_; 491cb0ef41Sopenharmony_ci Smi current_; 501cb0ef41Sopenharmony_ci int index_; 511cb0ef41Sopenharmony_ci int table_offset_; 521cb0ef41Sopenharmony_ci int table_end_; 531cb0ef41Sopenharmony_ci }; 541cb0ef41Sopenharmony_ci 551cb0ef41Sopenharmony_ci JumpTableTargetOffsets(const BytecodeArrayIterator* iterator, int table_start, 561cb0ef41Sopenharmony_ci int table_size, int case_value_base); 571cb0ef41Sopenharmony_ci 581cb0ef41Sopenharmony_ci iterator begin() const; 591cb0ef41Sopenharmony_ci iterator end() const; 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ci int size() const; 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_ci private: 641cb0ef41Sopenharmony_ci const BytecodeArrayIterator* iterator_; 651cb0ef41Sopenharmony_ci int table_start_; 661cb0ef41Sopenharmony_ci int table_size_; 671cb0ef41Sopenharmony_ci int case_value_base_; 681cb0ef41Sopenharmony_ci}; 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE BytecodeArrayIterator { 711cb0ef41Sopenharmony_ci public: 721cb0ef41Sopenharmony_ci BytecodeArrayIterator(Handle<BytecodeArray> bytecode_array, 731cb0ef41Sopenharmony_ci int initial_offset = 0); 741cb0ef41Sopenharmony_ci ~BytecodeArrayIterator(); 751cb0ef41Sopenharmony_ci 761cb0ef41Sopenharmony_ci BytecodeArrayIterator(const BytecodeArrayIterator&) = delete; 771cb0ef41Sopenharmony_ci BytecodeArrayIterator& operator=(const BytecodeArrayIterator&) = delete; 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci inline void Advance() { 801cb0ef41Sopenharmony_ci cursor_ += current_bytecode_size_without_prefix(); 811cb0ef41Sopenharmony_ci UpdateOperandScale(); 821cb0ef41Sopenharmony_ci } 831cb0ef41Sopenharmony_ci void SetOffset(int offset); 841cb0ef41Sopenharmony_ci void Reset() { SetOffset(0); } 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ci void ApplyDebugBreak(); 871cb0ef41Sopenharmony_ci 881cb0ef41Sopenharmony_ci inline Bytecode current_bytecode() const { 891cb0ef41Sopenharmony_ci DCHECK(!done()); 901cb0ef41Sopenharmony_ci uint8_t current_byte = *cursor_; 911cb0ef41Sopenharmony_ci Bytecode current_bytecode = Bytecodes::FromByte(current_byte); 921cb0ef41Sopenharmony_ci DCHECK(!Bytecodes::IsPrefixScalingBytecode(current_bytecode)); 931cb0ef41Sopenharmony_ci return current_bytecode; 941cb0ef41Sopenharmony_ci } 951cb0ef41Sopenharmony_ci int current_bytecode_size() const { 961cb0ef41Sopenharmony_ci return prefix_size_ + current_bytecode_size_without_prefix(); 971cb0ef41Sopenharmony_ci } 981cb0ef41Sopenharmony_ci int current_bytecode_size_without_prefix() const { 991cb0ef41Sopenharmony_ci return Bytecodes::Size(current_bytecode(), current_operand_scale()); 1001cb0ef41Sopenharmony_ci } 1011cb0ef41Sopenharmony_ci int current_offset() const { 1021cb0ef41Sopenharmony_ci return static_cast<int>(cursor_ - start_ - prefix_size_); 1031cb0ef41Sopenharmony_ci } 1041cb0ef41Sopenharmony_ci int next_offset() const { return current_offset() + current_bytecode_size(); } 1051cb0ef41Sopenharmony_ci OperandScale current_operand_scale() const { return operand_scale_; } 1061cb0ef41Sopenharmony_ci Handle<BytecodeArray> bytecode_array() const { return bytecode_array_; } 1071cb0ef41Sopenharmony_ci 1081cb0ef41Sopenharmony_ci uint32_t GetFlagOperand(int operand_index) const; 1091cb0ef41Sopenharmony_ci uint32_t GetUnsignedImmediateOperand(int operand_index) const; 1101cb0ef41Sopenharmony_ci int32_t GetImmediateOperand(int operand_index) const; 1111cb0ef41Sopenharmony_ci uint32_t GetIndexOperand(int operand_index) const; 1121cb0ef41Sopenharmony_ci FeedbackSlot GetSlotOperand(int operand_index) const; 1131cb0ef41Sopenharmony_ci Register GetReceiver() const; 1141cb0ef41Sopenharmony_ci Register GetParameter(int parameter_index) const; 1151cb0ef41Sopenharmony_ci uint32_t GetRegisterCountOperand(int operand_index) const; 1161cb0ef41Sopenharmony_ci Register GetRegisterOperand(int operand_index) const; 1171cb0ef41Sopenharmony_ci std::pair<Register, Register> GetRegisterPairOperand(int operand_index) const; 1181cb0ef41Sopenharmony_ci RegisterList GetRegisterListOperand(int operand_index) const; 1191cb0ef41Sopenharmony_ci int GetRegisterOperandRange(int operand_index) const; 1201cb0ef41Sopenharmony_ci Runtime::FunctionId GetRuntimeIdOperand(int operand_index) const; 1211cb0ef41Sopenharmony_ci Runtime::FunctionId GetIntrinsicIdOperand(int operand_index) const; 1221cb0ef41Sopenharmony_ci uint32_t GetNativeContextIndexOperand(int operand_index) const; 1231cb0ef41Sopenharmony_ci template <typename IsolateT> 1241cb0ef41Sopenharmony_ci Handle<Object> GetConstantAtIndex(int offset, IsolateT* isolate) const; 1251cb0ef41Sopenharmony_ci bool IsConstantAtIndexSmi(int offset) const; 1261cb0ef41Sopenharmony_ci Smi GetConstantAtIndexAsSmi(int offset) const; 1271cb0ef41Sopenharmony_ci template <typename IsolateT> 1281cb0ef41Sopenharmony_ci Handle<Object> GetConstantForIndexOperand(int operand_index, 1291cb0ef41Sopenharmony_ci IsolateT* isolate) const; 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ci // Returns the relative offset of the branch target at the current bytecode. 1321cb0ef41Sopenharmony_ci // It is an error to call this method if the bytecode is not for a jump or 1331cb0ef41Sopenharmony_ci // conditional jump. Returns a negative offset for backward jumps. 1341cb0ef41Sopenharmony_ci int GetRelativeJumpTargetOffset() const; 1351cb0ef41Sopenharmony_ci // Returns the absolute offset of the branch target at the current bytecode. 1361cb0ef41Sopenharmony_ci // It is an error to call this method if the bytecode is not for a jump or 1371cb0ef41Sopenharmony_ci // conditional jump. 1381cb0ef41Sopenharmony_ci int GetJumpTargetOffset() const; 1391cb0ef41Sopenharmony_ci // Returns an iterator over the absolute offsets of the targets of the current 1401cb0ef41Sopenharmony_ci // switch bytecode's jump table. It is an error to call this method if the 1411cb0ef41Sopenharmony_ci // bytecode is not a switch. 1421cb0ef41Sopenharmony_ci JumpTableTargetOffsets GetJumpTableTargetOffsets() const; 1431cb0ef41Sopenharmony_ci 1441cb0ef41Sopenharmony_ci // Returns the absolute offset of the bytecode at the given relative offset 1451cb0ef41Sopenharmony_ci // from the current bytecode. 1461cb0ef41Sopenharmony_ci int GetAbsoluteOffset(int relative_offset) const; 1471cb0ef41Sopenharmony_ci 1481cb0ef41Sopenharmony_ci std::ostream& PrintTo(std::ostream& os) const; 1491cb0ef41Sopenharmony_ci 1501cb0ef41Sopenharmony_ci static void UpdatePointersCallback(void* iterator) { 1511cb0ef41Sopenharmony_ci reinterpret_cast<BytecodeArrayIterator*>(iterator)->UpdatePointers(); 1521cb0ef41Sopenharmony_ci } 1531cb0ef41Sopenharmony_ci 1541cb0ef41Sopenharmony_ci void UpdatePointers(); 1551cb0ef41Sopenharmony_ci 1561cb0ef41Sopenharmony_ci inline bool done() const { return cursor_ >= end_; } 1571cb0ef41Sopenharmony_ci 1581cb0ef41Sopenharmony_ci private: 1591cb0ef41Sopenharmony_ci uint32_t GetUnsignedOperand(int operand_index, 1601cb0ef41Sopenharmony_ci OperandType operand_type) const; 1611cb0ef41Sopenharmony_ci int32_t GetSignedOperand(int operand_index, OperandType operand_type) const; 1621cb0ef41Sopenharmony_ci 1631cb0ef41Sopenharmony_ci inline void UpdateOperandScale() { 1641cb0ef41Sopenharmony_ci if (done()) return; 1651cb0ef41Sopenharmony_ci uint8_t current_byte = *cursor_; 1661cb0ef41Sopenharmony_ci Bytecode current_bytecode = Bytecodes::FromByte(current_byte); 1671cb0ef41Sopenharmony_ci if (Bytecodes::IsPrefixScalingBytecode(current_bytecode)) { 1681cb0ef41Sopenharmony_ci operand_scale_ = 1691cb0ef41Sopenharmony_ci Bytecodes::PrefixBytecodeToOperandScale(current_bytecode); 1701cb0ef41Sopenharmony_ci ++cursor_; 1711cb0ef41Sopenharmony_ci prefix_size_ = 1; 1721cb0ef41Sopenharmony_ci } else { 1731cb0ef41Sopenharmony_ci operand_scale_ = OperandScale::kSingle; 1741cb0ef41Sopenharmony_ci prefix_size_ = 0; 1751cb0ef41Sopenharmony_ci } 1761cb0ef41Sopenharmony_ci } 1771cb0ef41Sopenharmony_ci 1781cb0ef41Sopenharmony_ci Handle<BytecodeArray> bytecode_array_; 1791cb0ef41Sopenharmony_ci uint8_t* start_; 1801cb0ef41Sopenharmony_ci uint8_t* end_; 1811cb0ef41Sopenharmony_ci // The cursor always points to the active bytecode. If there's a prefix, the 1821cb0ef41Sopenharmony_ci // prefix is at (cursor - 1). 1831cb0ef41Sopenharmony_ci uint8_t* cursor_; 1841cb0ef41Sopenharmony_ci OperandScale operand_scale_; 1851cb0ef41Sopenharmony_ci int prefix_size_; 1861cb0ef41Sopenharmony_ci LocalHeap* const local_heap_; 1871cb0ef41Sopenharmony_ci}; 1881cb0ef41Sopenharmony_ci 1891cb0ef41Sopenharmony_ci} // namespace interpreter 1901cb0ef41Sopenharmony_ci} // namespace internal 1911cb0ef41Sopenharmony_ci} // namespace v8 1921cb0ef41Sopenharmony_ci 1931cb0ef41Sopenharmony_ci#endif // V8_INTERPRETER_BYTECODE_ARRAY_ITERATOR_H_ 194