1265091e581c9f643b37e7966890911f09e223269Brian Carlstrom/* 2265091e581c9f643b37e7966890911f09e223269Brian Carlstrom * Copyright (C) 2011 The Android Open Source Project 3265091e581c9f643b37e7966890911f09e223269Brian Carlstrom * 4265091e581c9f643b37e7966890911f09e223269Brian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License"); 5265091e581c9f643b37e7966890911f09e223269Brian Carlstrom * you may not use this file except in compliance with the License. 6265091e581c9f643b37e7966890911f09e223269Brian Carlstrom * You may obtain a copy of the License at 7265091e581c9f643b37e7966890911f09e223269Brian Carlstrom * 8265091e581c9f643b37e7966890911f09e223269Brian Carlstrom * http://www.apache.org/licenses/LICENSE-2.0 9265091e581c9f643b37e7966890911f09e223269Brian Carlstrom * 10265091e581c9f643b37e7966890911f09e223269Brian Carlstrom * Unless required by applicable law or agreed to in writing, software 11265091e581c9f643b37e7966890911f09e223269Brian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS, 12265091e581c9f643b37e7966890911f09e223269Brian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13265091e581c9f643b37e7966890911f09e223269Brian Carlstrom * See the License for the specific language governing permissions and 14265091e581c9f643b37e7966890911f09e223269Brian Carlstrom * limitations under the License. 15265091e581c9f643b37e7966890911f09e223269Brian Carlstrom */ 16265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_DEX_METHOD_ITERATOR_H_ 18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_DEX_METHOD_ITERATOR_H_ 19265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 20265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#include <vector> 21265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 22265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#include "dex_file.h" 23265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 24265091e581c9f643b37e7966890911f09e223269Brian Carlstromnamespace art { 25265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 26265091e581c9f643b37e7966890911f09e223269Brian Carlstromclass DexMethodIterator { 27265091e581c9f643b37e7966890911f09e223269Brian Carlstrom public: 2893ba893c20532990a430741e0a97212900094e8cBrian Carlstrom explicit DexMethodIterator(const std::vector<const DexFile*>& dex_files) 29265091e581c9f643b37e7966890911f09e223269Brian Carlstrom : dex_files_(dex_files), 30265091e581c9f643b37e7966890911f09e223269Brian Carlstrom found_next_(false), 31265091e581c9f643b37e7966890911f09e223269Brian Carlstrom dex_file_index_(0), 32265091e581c9f643b37e7966890911f09e223269Brian Carlstrom class_def_index_(0), 332cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier class_def_(nullptr), 342cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier class_data_(nullptr), 35265091e581c9f643b37e7966890911f09e223269Brian Carlstrom direct_method_(false) { 36265091e581c9f643b37e7966890911f09e223269Brian Carlstrom CHECK_NE(0U, dex_files_.size()); 37265091e581c9f643b37e7966890911f09e223269Brian Carlstrom } 38265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 39265091e581c9f643b37e7966890911f09e223269Brian Carlstrom bool HasNext() { 40265091e581c9f643b37e7966890911f09e223269Brian Carlstrom if (found_next_) { 41265091e581c9f643b37e7966890911f09e223269Brian Carlstrom return true; 42265091e581c9f643b37e7966890911f09e223269Brian Carlstrom } 43265091e581c9f643b37e7966890911f09e223269Brian Carlstrom while (true) { 44265091e581c9f643b37e7966890911f09e223269Brian Carlstrom // End of DexFiles, we are done. 45265091e581c9f643b37e7966890911f09e223269Brian Carlstrom if (dex_file_index_ == dex_files_.size()) { 46265091e581c9f643b37e7966890911f09e223269Brian Carlstrom return false; 47265091e581c9f643b37e7966890911f09e223269Brian Carlstrom } 48265091e581c9f643b37e7966890911f09e223269Brian Carlstrom if (class_def_index_ == GetDexFileInternal().NumClassDefs()) { 49265091e581c9f643b37e7966890911f09e223269Brian Carlstrom // End of this DexFile, advance and retry. 50265091e581c9f643b37e7966890911f09e223269Brian Carlstrom class_def_index_ = 0; 51265091e581c9f643b37e7966890911f09e223269Brian Carlstrom dex_file_index_++; 52265091e581c9f643b37e7966890911f09e223269Brian Carlstrom continue; 53265091e581c9f643b37e7966890911f09e223269Brian Carlstrom } 542cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (class_def_ == nullptr) { 55265091e581c9f643b37e7966890911f09e223269Brian Carlstrom class_def_ = &GetDexFileInternal().GetClassDef(class_def_index_); 56265091e581c9f643b37e7966890911f09e223269Brian Carlstrom } 572cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (class_data_ == nullptr) { 58265091e581c9f643b37e7966890911f09e223269Brian Carlstrom class_data_ = GetDexFileInternal().GetClassData(*class_def_); 592cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (class_data_ == nullptr) { 60265091e581c9f643b37e7966890911f09e223269Brian Carlstrom // empty class, such as a marker interface 61265091e581c9f643b37e7966890911f09e223269Brian Carlstrom // End of this class, advance and retry. 622cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier class_def_ = nullptr; 63265091e581c9f643b37e7966890911f09e223269Brian Carlstrom class_def_index_++; 64265091e581c9f643b37e7966890911f09e223269Brian Carlstrom continue; 65265091e581c9f643b37e7966890911f09e223269Brian Carlstrom } 66265091e581c9f643b37e7966890911f09e223269Brian Carlstrom } 672cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (it_.get() == nullptr) { 68265091e581c9f643b37e7966890911f09e223269Brian Carlstrom it_.reset(new ClassDataItemIterator(GetDexFileInternal(), class_data_)); 69265091e581c9f643b37e7966890911f09e223269Brian Carlstrom // Skip fields 70265091e581c9f643b37e7966890911f09e223269Brian Carlstrom while (GetIterator().HasNextStaticField()) { 71265091e581c9f643b37e7966890911f09e223269Brian Carlstrom GetIterator().Next(); 72265091e581c9f643b37e7966890911f09e223269Brian Carlstrom } 73265091e581c9f643b37e7966890911f09e223269Brian Carlstrom while (GetIterator().HasNextInstanceField()) { 74265091e581c9f643b37e7966890911f09e223269Brian Carlstrom GetIterator().Next(); 75265091e581c9f643b37e7966890911f09e223269Brian Carlstrom } 76265091e581c9f643b37e7966890911f09e223269Brian Carlstrom direct_method_ = true; 77265091e581c9f643b37e7966890911f09e223269Brian Carlstrom } 78265091e581c9f643b37e7966890911f09e223269Brian Carlstrom if (direct_method_ && GetIterator().HasNextDirectMethod()) { 79265091e581c9f643b37e7966890911f09e223269Brian Carlstrom // Found method 80265091e581c9f643b37e7966890911f09e223269Brian Carlstrom found_next_ = true; 81265091e581c9f643b37e7966890911f09e223269Brian Carlstrom return true; 82265091e581c9f643b37e7966890911f09e223269Brian Carlstrom } 83265091e581c9f643b37e7966890911f09e223269Brian Carlstrom direct_method_ = false; 84265091e581c9f643b37e7966890911f09e223269Brian Carlstrom if (GetIterator().HasNextVirtualMethod()) { 85265091e581c9f643b37e7966890911f09e223269Brian Carlstrom // Found method 86265091e581c9f643b37e7966890911f09e223269Brian Carlstrom found_next_ = true; 87265091e581c9f643b37e7966890911f09e223269Brian Carlstrom return true; 88265091e581c9f643b37e7966890911f09e223269Brian Carlstrom } 89265091e581c9f643b37e7966890911f09e223269Brian Carlstrom // End of this class, advance and retry. 90265091e581c9f643b37e7966890911f09e223269Brian Carlstrom DCHECK(!GetIterator().HasNext()); 912cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier it_.reset(nullptr); 922cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier class_data_ = nullptr; 932cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier class_def_ = nullptr; 94265091e581c9f643b37e7966890911f09e223269Brian Carlstrom class_def_index_++; 95265091e581c9f643b37e7966890911f09e223269Brian Carlstrom } 96265091e581c9f643b37e7966890911f09e223269Brian Carlstrom } 97265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 98265091e581c9f643b37e7966890911f09e223269Brian Carlstrom void Next() { 99265091e581c9f643b37e7966890911f09e223269Brian Carlstrom found_next_ = false; 1002cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (it_.get() != nullptr) { 101265091e581c9f643b37e7966890911f09e223269Brian Carlstrom // Advance to next method if we currently are looking at a class. 102265091e581c9f643b37e7966890911f09e223269Brian Carlstrom GetIterator().Next(); 103265091e581c9f643b37e7966890911f09e223269Brian Carlstrom } 104265091e581c9f643b37e7966890911f09e223269Brian Carlstrom } 105265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 106265091e581c9f643b37e7966890911f09e223269Brian Carlstrom const DexFile& GetDexFile() { 107265091e581c9f643b37e7966890911f09e223269Brian Carlstrom CHECK(HasNext()); 108265091e581c9f643b37e7966890911f09e223269Brian Carlstrom return GetDexFileInternal(); 109265091e581c9f643b37e7966890911f09e223269Brian Carlstrom } 110265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 111265091e581c9f643b37e7966890911f09e223269Brian Carlstrom uint32_t GetMemberIndex() { 112265091e581c9f643b37e7966890911f09e223269Brian Carlstrom CHECK(HasNext()); 113265091e581c9f643b37e7966890911f09e223269Brian Carlstrom return GetIterator().GetMemberIndex(); 114265091e581c9f643b37e7966890911f09e223269Brian Carlstrom } 115265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 116265091e581c9f643b37e7966890911f09e223269Brian Carlstrom InvokeType GetInvokeType() { 117265091e581c9f643b37e7966890911f09e223269Brian Carlstrom CHECK(HasNext()); 1182cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier CHECK(class_def_ != nullptr); 119265091e581c9f643b37e7966890911f09e223269Brian Carlstrom return GetIterator().GetMethodInvokeType(*class_def_); 120265091e581c9f643b37e7966890911f09e223269Brian Carlstrom } 121265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 122265091e581c9f643b37e7966890911f09e223269Brian Carlstrom private: 123265091e581c9f643b37e7966890911f09e223269Brian Carlstrom ClassDataItemIterator& GetIterator() const { 1242cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier CHECK(it_.get() != nullptr); 125265091e581c9f643b37e7966890911f09e223269Brian Carlstrom return *it_.get(); 126265091e581c9f643b37e7966890911f09e223269Brian Carlstrom } 127265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 128265091e581c9f643b37e7966890911f09e223269Brian Carlstrom const DexFile& GetDexFileInternal() const { 129265091e581c9f643b37e7966890911f09e223269Brian Carlstrom CHECK_LT(dex_file_index_, dex_files_.size()); 130265091e581c9f643b37e7966890911f09e223269Brian Carlstrom const DexFile* dex_file = dex_files_[dex_file_index_]; 1312cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier CHECK(dex_file != nullptr); 132265091e581c9f643b37e7966890911f09e223269Brian Carlstrom return *dex_file; 133265091e581c9f643b37e7966890911f09e223269Brian Carlstrom } 134265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 135265091e581c9f643b37e7966890911f09e223269Brian Carlstrom const std::vector<const DexFile*>& dex_files_; 136265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 137265091e581c9f643b37e7966890911f09e223269Brian Carlstrom bool found_next_; 138265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 139265091e581c9f643b37e7966890911f09e223269Brian Carlstrom uint32_t dex_file_index_; 140265091e581c9f643b37e7966890911f09e223269Brian Carlstrom uint32_t class_def_index_; 141265091e581c9f643b37e7966890911f09e223269Brian Carlstrom const DexFile::ClassDef* class_def_; 14213735955f39b3b304c37d2b2840663c131262c18Ian Rogers const uint8_t* class_data_; 143700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers std::unique_ptr<ClassDataItemIterator> it_; 144265091e581c9f643b37e7966890911f09e223269Brian Carlstrom bool direct_method_; 145265091e581c9f643b37e7966890911f09e223269Brian Carlstrom}; 146265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 147265091e581c9f643b37e7966890911f09e223269Brian Carlstrom} // namespace art 148265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 149fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_DEX_METHOD_ITERATOR_H_ 150