blob: 49ca98d47f1e3f59bc9910cac295d9ee8e0ee449 [file] [log] [blame]
Mathieu Chartierc2b4db62018-05-18 13:58:12 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_LIBDEXFILE_DEX_CLASS_ACCESSOR_INL_H_
18#define ART_LIBDEXFILE_DEX_CLASS_ACCESSOR_INL_H_
19
20#include "class_accessor.h"
21
22#include "base/leb128.h"
Mathieu Chartier05dc23e2018-05-22 11:56:14 -070023#include "class_iterator.h"
24#include "code_item_accessors-inl.h"
Mathieu Chartierc2b4db62018-05-18 13:58:12 -070025
26namespace art {
27
Mathieu Chartier05dc23e2018-05-22 11:56:14 -070028inline ClassAccessor::ClassAccessor(const ClassIteratorData& data)
29 : ClassAccessor(data.dex_file_, data.dex_file_.GetClassDef(data.class_def_idx_)) {}
Mathieu Chartierc2b4db62018-05-18 13:58:12 -070030
Mathieu Chartier05dc23e2018-05-22 11:56:14 -070031inline ClassAccessor::ClassAccessor(const DexFile& dex_file, const DexFile::ClassDef& class_def)
Mathieu Chartierc2b4db62018-05-18 13:58:12 -070032 : dex_file_(dex_file),
Mathieu Chartier05dc23e2018-05-22 11:56:14 -070033 descriptor_index_(class_def.class_idx_),
34 ptr_pos_(dex_file.GetClassData(class_def)),
35 num_static_fields_(ptr_pos_ != nullptr ? DecodeUnsignedLeb128(&ptr_pos_) : 0u),
36 num_instance_fields_(ptr_pos_ != nullptr ? DecodeUnsignedLeb128(&ptr_pos_) : 0u),
37 num_direct_methods_(ptr_pos_ != nullptr ? DecodeUnsignedLeb128(&ptr_pos_) : 0u),
38 num_virtual_methods_(ptr_pos_ != nullptr ? DecodeUnsignedLeb128(&ptr_pos_) : 0u) {}
Mathieu Chartierc2b4db62018-05-18 13:58:12 -070039
40inline const uint8_t* ClassAccessor::Method::Read(const uint8_t* ptr) {
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -070041 index_ += DecodeUnsignedLeb128(&ptr);
Mathieu Chartierc2b4db62018-05-18 13:58:12 -070042 access_flags_ = DecodeUnsignedLeb128(&ptr);
43 code_off_ = DecodeUnsignedLeb128(&ptr);
44 return ptr;
45}
46
47inline const uint8_t* ClassAccessor::Field::Read(const uint8_t* ptr) {
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -070048 index_ += DecodeUnsignedLeb128(&ptr);
Mathieu Chartierc2b4db62018-05-18 13:58:12 -070049 access_flags_ = DecodeUnsignedLeb128(&ptr);
50 return ptr;
51}
52
Mathieu Chartier0d896bd2018-05-25 00:20:27 -070053template <typename DataType, typename Visitor>
54inline const uint8_t* ClassAccessor::VisitMembers(size_t count,
55 const Visitor& visitor,
56 const uint8_t* ptr,
57 DataType* data) const {
58 DCHECK(data != nullptr);
59 for ( ; count != 0; --count) {
60 ptr = data->Read(ptr);
61 visitor(*data);
62 }
63 return ptr;
64}
65
Mathieu Chartierc2b4db62018-05-18 13:58:12 -070066template <typename StaticFieldVisitor,
67 typename InstanceFieldVisitor,
68 typename DirectMethodVisitor,
69 typename VirtualMethodVisitor>
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -070070inline void ClassAccessor::VisitFieldsAndMethods(
Mathieu Chartierc2b4db62018-05-18 13:58:12 -070071 const StaticFieldVisitor& static_field_visitor,
72 const InstanceFieldVisitor& instance_field_visitor,
73 const DirectMethodVisitor& direct_method_visitor,
74 const VirtualMethodVisitor& virtual_method_visitor) const {
Mathieu Chartier0d896bd2018-05-25 00:20:27 -070075 Field field(dex_file_);
76 const uint8_t* ptr = VisitMembers(num_static_fields_, static_field_visitor, ptr_pos_, &field);
77 field.NextSection();
78 ptr = VisitMembers(num_instance_fields_, instance_field_visitor, ptr, &field);
79
80 Method method(dex_file_, /*is_static_or_direct*/ true);
81 ptr = VisitMembers(num_direct_methods_, direct_method_visitor, ptr, &method);
82 method.NextSection();
83 ptr = VisitMembers(num_virtual_methods_, virtual_method_visitor, ptr, &method);
Mathieu Chartierc2b4db62018-05-18 13:58:12 -070084}
85
86template <typename DirectMethodVisitor,
87 typename VirtualMethodVisitor>
88inline void ClassAccessor::VisitMethods(const DirectMethodVisitor& direct_method_visitor,
89 const VirtualMethodVisitor& virtual_method_visitor) const {
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -070090 VisitFieldsAndMethods(VoidFunctor(),
Mathieu Chartierc2b4db62018-05-18 13:58:12 -070091 VoidFunctor(),
92 direct_method_visitor,
93 virtual_method_visitor);
94}
95
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -070096template <typename StaticFieldVisitor,
97 typename InstanceFieldVisitor>
98inline void ClassAccessor::VisitFields(const StaticFieldVisitor& static_field_visitor,
99 const InstanceFieldVisitor& instance_field_visitor) const {
100 VisitFieldsAndMethods(static_field_visitor,
101 instance_field_visitor,
102 VoidFunctor(),
103 VoidFunctor());
104}
105
Mathieu Chartierc2b4db62018-05-18 13:58:12 -0700106inline const DexFile::CodeItem* ClassAccessor::GetCodeItem(const Method& method) const {
107 return dex_file_.GetCodeItem(method.GetCodeItemOffset());
108}
109
Mathieu Chartier05dc23e2018-05-22 11:56:14 -0700110inline CodeItemInstructionAccessor ClassAccessor::Method::GetInstructions() const {
111 return CodeItemInstructionAccessor(dex_file_, dex_file_.GetCodeItem(GetCodeItemOffset()));
112}
113
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -0700114inline const char* ClassAccessor::GetDescriptor() const {
115 return dex_file_.StringByTypeIdx(descriptor_index_);
116}
117
118inline const DexFile::CodeItem* ClassAccessor::Method::GetCodeItem() const {
119 return dex_file_.GetCodeItem(code_off_);
120}
121
Mathieu Chartier0d896bd2018-05-25 00:20:27 -0700122inline IterationRange<ClassAccessor::DataIterator<ClassAccessor::Field>> ClassAccessor::GetFields()
123 const {
124 const uint32_t limit = num_static_fields_ + num_instance_fields_;
125 return { DataIterator<Field>(dex_file_, 0u, num_static_fields_, limit, ptr_pos_),
126 DataIterator<Field>(dex_file_, limit, num_static_fields_, limit, ptr_pos_) };
127}
128
129inline IterationRange<ClassAccessor::DataIterator<ClassAccessor::Method>>
130 ClassAccessor::GetMethods() const {
131 // Skip over the fields.
132 Field field(dex_file_);
133 const size_t skip_count = num_static_fields_ + num_instance_fields_;
134 const uint8_t* ptr_pos = VisitMembers(skip_count, VoidFunctor(), ptr_pos_, &field);
135 // Return the iterator pair for all the methods.
136 const uint32_t limit = num_direct_methods_ + num_virtual_methods_;
137 return { DataIterator<Method>(dex_file_, 0u, num_direct_methods_, limit, ptr_pos),
138 DataIterator<Method>(dex_file_, limit, num_direct_methods_, limit, ptr_pos) };
139}
140
Mathieu Chartierc2b4db62018-05-18 13:58:12 -0700141} // namespace art
142
143#endif // ART_LIBDEXFILE_DEX_CLASS_ACCESSOR_INL_H_