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