summaryrefslogtreecommitdiffstats
path: root/runtime/dex_method_iterator.h
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/dex_method_iterator.h')
-rw-r--r--runtime/dex_method_iterator.h150
1 files changed, 150 insertions, 0 deletions
diff --git a/runtime/dex_method_iterator.h b/runtime/dex_method_iterator.h
new file mode 100644
index 0000000..dc2e712
--- /dev/null
+++ b/runtime/dex_method_iterator.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_DEX_METHOD_ITERATOR_H_
+#define ART_SRC_DEX_METHOD_ITERATOR_H_
+
+#include <vector>
+
+#include "dex_file.h"
+
+namespace art {
+
+class DexMethodIterator {
+ public:
+ DexMethodIterator(const std::vector<const DexFile*>& dex_files)
+ : dex_files_(dex_files),
+ found_next_(false),
+ dex_file_index_(0),
+ class_def_index_(0),
+ class_def_(NULL),
+ class_data_(NULL),
+ direct_method_(false) {
+ CHECK_NE(0U, dex_files_.size());
+ }
+
+ bool HasNext() {
+ if (found_next_) {
+ return true;
+ }
+ while (true) {
+ // End of DexFiles, we are done.
+ if (dex_file_index_ == dex_files_.size()) {
+ return false;
+ }
+ if (class_def_index_ == GetDexFileInternal().NumClassDefs()) {
+ // End of this DexFile, advance and retry.
+ class_def_index_ = 0;
+ dex_file_index_++;
+ continue;
+ }
+ if (class_def_ == NULL) {
+ class_def_ = &GetDexFileInternal().GetClassDef(class_def_index_);
+ }
+ if (class_data_ == NULL) {
+ class_data_ = GetDexFileInternal().GetClassData(*class_def_);
+ if (class_data_ == NULL) {
+ // empty class, such as a marker interface
+ // End of this class, advance and retry.
+ class_def_ = NULL;
+ class_def_index_++;
+ continue;
+ }
+ }
+ if (it_.get() == NULL) {
+ it_.reset(new ClassDataItemIterator(GetDexFileInternal(), class_data_));
+ // Skip fields
+ while (GetIterator().HasNextStaticField()) {
+ GetIterator().Next();
+ }
+ while (GetIterator().HasNextInstanceField()) {
+ GetIterator().Next();
+ }
+ direct_method_ = true;
+ }
+ if (direct_method_ && GetIterator().HasNextDirectMethod()) {
+ // Found method
+ found_next_ = true;
+ return true;
+ }
+ direct_method_ = false;
+ if (GetIterator().HasNextVirtualMethod()) {
+ // Found method
+ found_next_ = true;
+ return true;
+ }
+ // End of this class, advance and retry.
+ DCHECK(!GetIterator().HasNext());
+ it_.reset(NULL);
+ class_data_ = NULL;
+ class_def_ = NULL;
+ class_def_index_++;
+ }
+ }
+
+ void Next() {
+ found_next_ = false;
+ if (it_.get() != NULL) {
+ // Advance to next method if we currently are looking at a class.
+ GetIterator().Next();
+ }
+ }
+
+ const DexFile& GetDexFile() {
+ CHECK(HasNext());
+ return GetDexFileInternal();
+ }
+
+ uint32_t GetMemberIndex() {
+ CHECK(HasNext());
+ return GetIterator().GetMemberIndex();
+ }
+
+ InvokeType GetInvokeType() {
+ CHECK(HasNext());
+ CHECK(class_def_ != NULL);
+ return GetIterator().GetMethodInvokeType(*class_def_);
+ }
+
+ private:
+
+ ClassDataItemIterator& GetIterator() const {
+ CHECK(it_.get() != NULL);
+ return *it_.get();
+ }
+
+ const DexFile& GetDexFileInternal() const {
+ CHECK_LT(dex_file_index_, dex_files_.size());
+ const DexFile* dex_file = dex_files_[dex_file_index_];
+ CHECK(dex_file != NULL);
+ return *dex_file;
+ }
+
+ const std::vector<const DexFile*>& dex_files_;
+
+ bool found_next_;
+
+ uint32_t dex_file_index_;
+ uint32_t class_def_index_;
+ const DexFile::ClassDef* class_def_;
+ const byte* class_data_;
+ UniquePtr<ClassDataItemIterator> it_;
+ bool direct_method_;
+};
+
+} // namespace art
+
+#endif // ART_SRC_DEX_METHOD_ITERATOR_H_