Add ClassIterator
Add a way to iterate over all of the classes in a Dex file. The
iterator returns a ClassAccessor for each class.
Added DexFile::GetClasses to return an iteration range for this new
iterator type.
Sample usage:
for (ClassAccessor accessor : dex_file.GetClasses()) {
Bug: 79758018
Bug: 77709234
Test: test-art-host
Change-Id: I66e000aa11f433e72f6857496f4e89a0b811f5a2
diff --git a/libdexfile/dex/class_accessor-inl.h b/libdexfile/dex/class_accessor-inl.h
index bcd0a7b..5cfbcaa 100644
--- a/libdexfile/dex/class_accessor-inl.h
+++ b/libdexfile/dex/class_accessor-inl.h
@@ -20,19 +20,22 @@
#include "class_accessor.h"
#include "base/leb128.h"
+#include "class_iterator.h"
+#include "code_item_accessors-inl.h"
namespace art {
-inline ClassAccessor::ClassAccessor(const DexFile& dex_file, const DexFile::ClassDef& class_def)
- : ClassAccessor(dex_file, dex_file.GetClassData(class_def)) {}
+inline ClassAccessor::ClassAccessor(const ClassIteratorData& data)
+ : ClassAccessor(data.dex_file_, data.dex_file_.GetClassDef(data.class_def_idx_)) {}
-inline ClassAccessor::ClassAccessor(const DexFile& dex_file, const uint8_t* class_data)
+inline ClassAccessor::ClassAccessor(const DexFile& dex_file, const DexFile::ClassDef& class_def)
: dex_file_(dex_file),
- ptr_pos_(class_data),
- num_static_fields_(class_data != nullptr ? DecodeUnsignedLeb128(&ptr_pos_) : 0u),
- num_instance_fields_(class_data != nullptr ? DecodeUnsignedLeb128(&ptr_pos_) : 0u),
- num_direct_methods_(class_data != nullptr ? DecodeUnsignedLeb128(&ptr_pos_) : 0u),
- num_virtual_methods_(class_data != nullptr ? DecodeUnsignedLeb128(&ptr_pos_) : 0u) {}
+ descriptor_index_(class_def.class_idx_),
+ ptr_pos_(dex_file.GetClassData(class_def)),
+ num_static_fields_(ptr_pos_ != nullptr ? DecodeUnsignedLeb128(&ptr_pos_) : 0u),
+ num_instance_fields_(ptr_pos_ != nullptr ? DecodeUnsignedLeb128(&ptr_pos_) : 0u),
+ num_direct_methods_(ptr_pos_ != nullptr ? DecodeUnsignedLeb128(&ptr_pos_) : 0u),
+ num_virtual_methods_(ptr_pos_ != nullptr ? DecodeUnsignedLeb128(&ptr_pos_) : 0u) {}
inline const uint8_t* ClassAccessor::Method::Read(const uint8_t* ptr) {
method_idx_ += DecodeUnsignedLeb128(&ptr);
@@ -57,25 +60,33 @@
const DirectMethodVisitor& direct_method_visitor,
const VirtualMethodVisitor& virtual_method_visitor) const {
const uint8_t* ptr = ptr_pos_;
- for (size_t i = 0; i < num_static_fields_; ++i) {
+ {
Field data;
- ptr = data.Read(ptr);
- static_field_visitor(data);
+ for (size_t i = 0; i < num_static_fields_; ++i) {
+ ptr = data.Read(ptr);
+ static_field_visitor(data);
+ }
}
- for (size_t i = 0; i < num_instance_fields_; ++i) {
+ {
Field data;
- ptr = data.Read(ptr);
- instance_field_visitor(data);
+ for (size_t i = 0; i < num_instance_fields_; ++i) {
+ ptr = data.Read(ptr);
+ instance_field_visitor(data);
+ }
}
- for (size_t i = 0; i < num_direct_methods_; ++i) {
- Method data;
- ptr = data.Read(ptr);
- direct_method_visitor(data);
+ {
+ Method data(dex_file_);
+ for (size_t i = 0; i < num_direct_methods_; ++i) {
+ ptr = data.Read(ptr);
+ direct_method_visitor(data);
+ }
}
- for (size_t i = 0; i < num_virtual_methods_; ++i) {
- Method data;
- ptr = data.Read(ptr);
- virtual_method_visitor(data);
+ {
+ Method data(dex_file_);
+ for (size_t i = 0; i < num_virtual_methods_; ++i) {
+ ptr = data.Read(ptr);
+ virtual_method_visitor(data);
+ }
}
}
@@ -99,6 +110,10 @@
return dex_file_.GetCodeItem(method.GetCodeItemOffset());
}
+inline CodeItemInstructionAccessor ClassAccessor::Method::GetInstructions() const {
+ return CodeItemInstructionAccessor(dex_file_, dex_file_.GetCodeItem(GetCodeItemOffset()));
+}
+
} // namespace art
#endif // ART_LIBDEXFILE_DEX_CLASS_ACCESSOR_INL_H_