blob: f224a29fc44863b9cfa60325e968db6a04fc9f88 [file] [log] [blame]
Martin Stjernholmc15e7e42020-12-02 22:50:53 +00001/*
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/hiddenapi_flags.h"
23#include "base/leb128.h"
24#include "base/utils.h"
25#include "class_iterator.h"
26#include "code_item_accessors-inl.h"
27#include "dex_file.h"
28#include "method_reference.h"
29
30namespace art {
31
32inline ClassAccessor::ClassAccessor(const ClassIteratorData& data)
33 : ClassAccessor(data.dex_file_, data.class_def_idx_) {}
34
35inline ClassAccessor::ClassAccessor(const DexFile& dex_file,
36 const dex::ClassDef& class_def,
37 bool parse_hiddenapi_class_data)
38 : ClassAccessor(dex_file,
39 dex_file.GetClassData(class_def),
40 dex_file.GetIndexForClassDef(class_def),
41 parse_hiddenapi_class_data) {}
42
43inline ClassAccessor::ClassAccessor(const DexFile& dex_file, uint32_t class_def_index)
44 : ClassAccessor(dex_file, dex_file.GetClassDef(class_def_index)) {}
45
46inline ClassAccessor::ClassAccessor(const DexFile& dex_file,
47 const uint8_t* class_data,
48 uint32_t class_def_index,
49 bool parse_hiddenapi_class_data)
50 : dex_file_(dex_file),
51 class_def_index_(class_def_index),
52 ptr_pos_(class_data),
53 hiddenapi_ptr_pos_(nullptr),
54 num_static_fields_(ptr_pos_ != nullptr ? DecodeUnsignedLeb128(&ptr_pos_) : 0u),
55 num_instance_fields_(ptr_pos_ != nullptr ? DecodeUnsignedLeb128(&ptr_pos_) : 0u),
56 num_direct_methods_(ptr_pos_ != nullptr ? DecodeUnsignedLeb128(&ptr_pos_) : 0u),
57 num_virtual_methods_(ptr_pos_ != nullptr ? DecodeUnsignedLeb128(&ptr_pos_) : 0u) {
58 if (parse_hiddenapi_class_data && class_def_index != DexFile::kDexNoIndex32) {
59 const dex::HiddenapiClassData* hiddenapi_class_data = dex_file.GetHiddenapiClassData();
60 if (hiddenapi_class_data != nullptr) {
61 hiddenapi_ptr_pos_ = hiddenapi_class_data->GetFlagsPointer(class_def_index);
62 }
63 }
64}
65
66inline void ClassAccessor::Method::Read() {
67 index_ += DecodeUnsignedLeb128(&ptr_pos_);
68 access_flags_ = DecodeUnsignedLeb128(&ptr_pos_);
69 code_off_ = DecodeUnsignedLeb128(&ptr_pos_);
70 if (hiddenapi_ptr_pos_ != nullptr) {
71 hiddenapi_flags_ = DecodeUnsignedLeb128(&hiddenapi_ptr_pos_);
72 DCHECK(hiddenapi::ApiList(hiddenapi_flags_).IsValid());
73 }
74}
75
76inline MethodReference ClassAccessor::Method::GetReference() const {
77 return MethodReference(&dex_file_, GetIndex());
78}
79
80
81inline void ClassAccessor::Field::Read() {
82 index_ += DecodeUnsignedLeb128(&ptr_pos_);
83 access_flags_ = DecodeUnsignedLeb128(&ptr_pos_);
84 if (hiddenapi_ptr_pos_ != nullptr) {
85 hiddenapi_flags_ = DecodeUnsignedLeb128(&hiddenapi_ptr_pos_);
86 DCHECK(hiddenapi::ApiList(hiddenapi_flags_).IsValid());
87 }
88}
89
90template <typename DataType, typename Visitor>
91inline void ClassAccessor::VisitMembers(size_t count,
92 const Visitor& visitor,
93 DataType* data) const {
94 DCHECK(data != nullptr);
95 for ( ; count != 0; --count) {
96 data->Read();
97 visitor(*data);
98 }
99}
100
101template <typename StaticFieldVisitor,
102 typename InstanceFieldVisitor,
103 typename DirectMethodVisitor,
104 typename VirtualMethodVisitor>
105inline void ClassAccessor::VisitFieldsAndMethods(
106 const StaticFieldVisitor& static_field_visitor,
107 const InstanceFieldVisitor& instance_field_visitor,
108 const DirectMethodVisitor& direct_method_visitor,
109 const VirtualMethodVisitor& virtual_method_visitor) const {
110 Field field(dex_file_, ptr_pos_, hiddenapi_ptr_pos_);
111 VisitMembers(num_static_fields_, static_field_visitor, &field);
112 field.NextSection();
113 VisitMembers(num_instance_fields_, instance_field_visitor, &field);
114
115 Method method(dex_file_, field.ptr_pos_, field.hiddenapi_ptr_pos_, /*is_static_or_direct*/ true);
116 VisitMembers(num_direct_methods_, direct_method_visitor, &method);
117 method.NextSection();
118 VisitMembers(num_virtual_methods_, virtual_method_visitor, &method);
119}
120
121template <typename DirectMethodVisitor,
122 typename VirtualMethodVisitor>
123inline void ClassAccessor::VisitMethods(const DirectMethodVisitor& direct_method_visitor,
124 const VirtualMethodVisitor& virtual_method_visitor) const {
125 VisitFieldsAndMethods(VoidFunctor(),
126 VoidFunctor(),
127 direct_method_visitor,
128 virtual_method_visitor);
129}
130
131template <typename StaticFieldVisitor,
132 typename InstanceFieldVisitor>
133inline void ClassAccessor::VisitFields(const StaticFieldVisitor& static_field_visitor,
134 const InstanceFieldVisitor& instance_field_visitor) const {
135 VisitFieldsAndMethods(static_field_visitor,
136 instance_field_visitor,
137 VoidFunctor(),
138 VoidFunctor());
139}
140
141inline const dex::CodeItem* ClassAccessor::GetCodeItem(const Method& method) const {
142 return dex_file_.GetCodeItem(method.GetCodeItemOffset());
143}
144
145inline CodeItemInstructionAccessor ClassAccessor::Method::GetInstructions() const {
146 return CodeItemInstructionAccessor(dex_file_, dex_file_.GetCodeItem(GetCodeItemOffset()));
147}
148
149inline CodeItemDataAccessor ClassAccessor::Method::GetInstructionsAndData() const {
150 return CodeItemDataAccessor(dex_file_, dex_file_.GetCodeItem(GetCodeItemOffset()));
151}
152
153inline const char* ClassAccessor::GetDescriptor() const {
154 return dex_file_.StringByTypeIdx(GetClassIdx());
155}
156
157inline const dex::CodeItem* ClassAccessor::Method::GetCodeItem() const {
158 return dex_file_.GetCodeItem(code_off_);
159}
160
161inline IterationRange<ClassAccessor::DataIterator<ClassAccessor::Field>>
162 ClassAccessor::GetFieldsInternal(size_t count) const {
163 return {
164 DataIterator<Field>(dex_file_,
165 0u,
166 num_static_fields_,
167 count,
168 ptr_pos_,
169 hiddenapi_ptr_pos_),
170 DataIterator<Field>(dex_file_,
171 count,
172 num_static_fields_,
173 count,
174 // The following pointers are bogus but unused in the `end` iterator.
175 ptr_pos_,
176 hiddenapi_ptr_pos_) };
177}
178
179// Return an iteration range for the first <count> methods.
180inline IterationRange<ClassAccessor::DataIterator<ClassAccessor::Method>>
181 ClassAccessor::GetMethodsInternal(size_t count) const {
182 // Skip over the fields.
183 Field field(dex_file_, ptr_pos_, hiddenapi_ptr_pos_);
184 VisitMembers(NumFields(), VoidFunctor(), &field);
185 // Return the iterator pair.
186 return {
187 DataIterator<Method>(dex_file_,
188 0u,
189 num_direct_methods_,
190 count,
191 field.ptr_pos_,
192 field.hiddenapi_ptr_pos_),
193 DataIterator<Method>(dex_file_,
194 count,
195 num_direct_methods_,
196 count,
197 // The following pointers are bogus but unused in the `end` iterator.
198 field.ptr_pos_,
199 field.hiddenapi_ptr_pos_) };
200}
201
202inline IterationRange<ClassAccessor::DataIterator<ClassAccessor::Field>> ClassAccessor::GetFields()
203 const {
204 return GetFieldsInternal(num_static_fields_ + num_instance_fields_);
205}
206
207inline IterationRange<ClassAccessor::DataIterator<ClassAccessor::Field>>
208 ClassAccessor::GetStaticFields() const {
209 return GetFieldsInternal(num_static_fields_);
210}
211
212
213inline IterationRange<ClassAccessor::DataIterator<ClassAccessor::Field>>
214 ClassAccessor::GetInstanceFields() const {
215 IterationRange<ClassAccessor::DataIterator<ClassAccessor::Field>> fields = GetFields();
216 // Skip the static fields.
217 return { std::next(fields.begin(), NumStaticFields()), fields.end() };
218}
219
220inline IterationRange<ClassAccessor::DataIterator<ClassAccessor::Method>>
221 ClassAccessor::GetMethods() const {
222 return GetMethodsInternal(NumMethods());
223}
224
225inline IterationRange<ClassAccessor::DataIterator<ClassAccessor::Method>>
226 ClassAccessor::GetDirectMethods() const {
227 return GetMethodsInternal(NumDirectMethods());
228}
229
230inline IterationRange<ClassAccessor::DataIterator<ClassAccessor::Method>>
231 ClassAccessor::GetVirtualMethods() const {
232 IterationRange<DataIterator<Method>> methods = GetMethods();
233 // Skip the direct fields.
234 return { std::next(methods.begin(), NumDirectMethods()), methods.end() };
235}
236
237inline dex::TypeIndex ClassAccessor::GetClassIdx() const {
238 return dex_file_.GetClassDef(class_def_index_).class_idx_;
239}
240
241inline const dex::ClassDef& ClassAccessor::GetClassDef() const {
242 return dex_file_.GetClassDef(GetClassDefIndex());
243}
244
245} // namespace art
246
247#endif // ART_LIBDEXFILE_DEX_CLASS_ACCESSOR_INL_H_