blob: 6c42bacf6316643bcf33a526a7e7d00961dbf1cf [file] [log] [blame]
David Sehr7629f602016-08-07 16:01:51 -07001/*
2 * Copyright (C) 2016 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 * Header file of an in-memory representation of DEX files.
17 */
18
19#ifndef ART_DEXLAYOUT_DEX_IR_H_
20#define ART_DEXLAYOUT_DEX_IR_H_
21
David Sehr7629f602016-08-07 16:01:51 -070022#include <vector>
23#include <stdint.h>
24
David Sehr853a8e12016-09-01 13:03:50 -070025#include "dex_file-inl.h"
Jeff Hao3ab96b42016-09-09 18:35:01 -070026#include "leb128.h"
Jeff Hao69b58cf2016-09-22 18:02:49 -070027#include "utf.h"
David Sehr7629f602016-08-07 16:01:51 -070028
29namespace art {
30namespace dex_ir {
31
32// Forward declarations for classes used in containers or pointed to.
Jeff Hao3ab96b42016-09-09 18:35:01 -070033class AnnotationItem;
David Sehr7629f602016-08-07 16:01:51 -070034class AnnotationsDirectoryItem;
35class AnnotationSetItem;
Jeff Hao3ab96b42016-09-09 18:35:01 -070036class AnnotationSetRefList;
David Sehr7629f602016-08-07 16:01:51 -070037class ClassData;
38class ClassDef;
39class CodeItem;
40class DebugInfoItem;
Jeff Hao3ab96b42016-09-09 18:35:01 -070041class EncodedAnnotation;
42class EncodedArrayItem;
43class EncodedValue;
David Sehr7629f602016-08-07 16:01:51 -070044class FieldId;
45class FieldItem;
46class Header;
47class MapList;
48class MapItem;
49class MethodId;
50class MethodItem;
Jeff Hao3ab96b42016-09-09 18:35:01 -070051class ParameterAnnotation;
David Sehr7629f602016-08-07 16:01:51 -070052class ProtoId;
Jeff Hao3ab96b42016-09-09 18:35:01 -070053class StringData;
David Sehr7629f602016-08-07 16:01:51 -070054class StringId;
55class TryItem;
56class TypeId;
Jeff Hao3ab96b42016-09-09 18:35:01 -070057class TypeList;
58
59// Item size constants.
60static constexpr size_t kHeaderItemSize = 112;
61static constexpr size_t kStringIdItemSize = 4;
62static constexpr size_t kTypeIdItemSize = 4;
63static constexpr size_t kProtoIdItemSize = 12;
64static constexpr size_t kFieldIdItemSize = 8;
65static constexpr size_t kMethodIdItemSize = 8;
66static constexpr size_t kClassDefItemSize = 32;
David Sehr7629f602016-08-07 16:01:51 -070067
68// Visitor support
69class AbstractDispatcher {
70 public:
71 AbstractDispatcher() = default;
72 virtual ~AbstractDispatcher() { }
73
74 virtual void Dispatch(Header* header) = 0;
Jeff Hao3ab96b42016-09-09 18:35:01 -070075 virtual void Dispatch(const StringData* string_data) = 0;
David Sehr7629f602016-08-07 16:01:51 -070076 virtual void Dispatch(const StringId* string_id) = 0;
77 virtual void Dispatch(const TypeId* type_id) = 0;
78 virtual void Dispatch(const ProtoId* proto_id) = 0;
79 virtual void Dispatch(const FieldId* field_id) = 0;
80 virtual void Dispatch(const MethodId* method_id) = 0;
81 virtual void Dispatch(ClassData* class_data) = 0;
82 virtual void Dispatch(ClassDef* class_def) = 0;
83 virtual void Dispatch(FieldItem* field_item) = 0;
84 virtual void Dispatch(MethodItem* method_item) = 0;
Jeff Hao3ab96b42016-09-09 18:35:01 -070085 virtual void Dispatch(EncodedArrayItem* array_item) = 0;
David Sehr7629f602016-08-07 16:01:51 -070086 virtual void Dispatch(CodeItem* code_item) = 0;
87 virtual void Dispatch(TryItem* try_item) = 0;
88 virtual void Dispatch(DebugInfoItem* debug_info_item) = 0;
Jeff Hao3ab96b42016-09-09 18:35:01 -070089 virtual void Dispatch(AnnotationItem* annotation_item) = 0;
David Sehr7629f602016-08-07 16:01:51 -070090 virtual void Dispatch(AnnotationSetItem* annotation_set_item) = 0;
Jeff Hao3ab96b42016-09-09 18:35:01 -070091 virtual void Dispatch(AnnotationSetRefList* annotation_set_ref_list) = 0;
David Sehr7629f602016-08-07 16:01:51 -070092 virtual void Dispatch(AnnotationsDirectoryItem* annotations_directory_item) = 0;
93 virtual void Dispatch(MapList* map_list) = 0;
94 virtual void Dispatch(MapItem* map_item) = 0;
95
96 private:
97 DISALLOW_COPY_AND_ASSIGN(AbstractDispatcher);
98};
99
100// Collections become owners of the objects added by moving them into unique pointers.
101template<class T> class CollectionWithOffset {
102 public:
103 CollectionWithOffset() = default;
104 std::vector<std::unique_ptr<T>>& Collection() { return collection_; }
105 // Read-time support methods
Jeff Hao3ab96b42016-09-09 18:35:01 -0700106 void AddItem(T* object, uint32_t offset) {
107 object->SetOffset(offset);
David Sehr7629f602016-08-07 16:01:51 -0700108 collection_.push_back(std::unique_ptr<T>(object));
Jeff Hao3ab96b42016-09-09 18:35:01 -0700109 }
110 void AddIndexedItem(T* object, uint32_t offset, uint32_t index) {
111 object->SetOffset(offset);
112 object->SetIndex(index);
113 collection_.push_back(std::unique_ptr<T>(object));
David Sehr7629f602016-08-07 16:01:51 -0700114 }
115 // Ordinary object insertion into collection.
116 void Insert(T object ATTRIBUTE_UNUSED) {
117 // TODO(sehr): add ordered insertion support.
118 UNIMPLEMENTED(FATAL) << "Insertion not ready";
119 }
120 uint32_t GetOffset() const { return offset_; }
121 void SetOffset(uint32_t new_offset) { offset_ = new_offset; }
122 uint32_t Size() const { return collection_.size(); }
123
124 private:
125 std::vector<std::unique_ptr<T>> collection_;
126 uint32_t offset_ = 0;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700127
David Sehr7629f602016-08-07 16:01:51 -0700128 DISALLOW_COPY_AND_ASSIGN(CollectionWithOffset);
129};
130
Jeff Hao3ab96b42016-09-09 18:35:01 -0700131class Collections {
132 public:
133 Collections() = default;
134
135 std::vector<std::unique_ptr<StringId>>& StringIds() { return string_ids_.Collection(); }
136 std::vector<std::unique_ptr<TypeId>>& TypeIds() { return type_ids_.Collection(); }
137 std::vector<std::unique_ptr<ProtoId>>& ProtoIds() { return proto_ids_.Collection(); }
138 std::vector<std::unique_ptr<FieldId>>& FieldIds() { return field_ids_.Collection(); }
139 std::vector<std::unique_ptr<MethodId>>& MethodIds() { return method_ids_.Collection(); }
140 std::vector<std::unique_ptr<ClassDef>>& ClassDefs() { return class_defs_.Collection(); }
Jeff Hao69b58cf2016-09-22 18:02:49 -0700141 std::vector<std::unique_ptr<StringData>>& StringDatas() { return string_datas_.Collection(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700142 std::vector<std::unique_ptr<TypeList>>& TypeLists() { return type_lists_.Collection(); }
143 std::vector<std::unique_ptr<EncodedArrayItem>>& EncodedArrayItems()
144 { return encoded_array_items_.Collection(); }
Jeff Hao69b58cf2016-09-22 18:02:49 -0700145 std::vector<std::unique_ptr<AnnotationItem>>& AnnotationItems()
146 { return annotation_items_.Collection(); }
147 std::vector<std::unique_ptr<AnnotationSetItem>>& AnnotationSetItems()
148 { return annotation_set_items_.Collection(); }
149 std::vector<std::unique_ptr<AnnotationSetRefList>>& AnnotationSetRefLists()
150 { return annotation_set_ref_lists_.Collection(); }
151 std::vector<std::unique_ptr<AnnotationsDirectoryItem>>& AnnotationsDirectoryItems()
152 { return annotations_directory_items_.Collection(); }
153 std::vector<std::unique_ptr<DebugInfoItem>>& DebugInfoItems()
154 { return debug_info_items_.Collection(); }
155 std::vector<std::unique_ptr<CodeItem>>& CodeItems() { return code_items_.Collection(); }
156 std::vector<std::unique_ptr<ClassData>>& ClassDatas() { return class_datas_.Collection(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700157
158 void CreateStringId(const DexFile& dex_file, uint32_t i);
159 void CreateTypeId(const DexFile& dex_file, uint32_t i);
160 void CreateProtoId(const DexFile& dex_file, uint32_t i);
161 void CreateFieldId(const DexFile& dex_file, uint32_t i);
162 void CreateMethodId(const DexFile& dex_file, uint32_t i);
163 void CreateClassDef(const DexFile& dex_file, uint32_t i);
164
Jeff Hao69b58cf2016-09-22 18:02:49 -0700165 TypeList* CreateTypeList(const DexFile::TypeList* type_list, uint32_t offset);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700166 EncodedArrayItem* CreateEncodedArrayItem(const uint8_t* static_data, uint32_t offset);
167 AnnotationItem* CreateAnnotationItem(const DexFile::AnnotationItem* annotation, uint32_t offset);
168 AnnotationSetItem* CreateAnnotationSetItem(const DexFile& dex_file,
169 const DexFile::AnnotationSetItem& disk_annotations_item, uint32_t offset);
170 AnnotationsDirectoryItem* CreateAnnotationsDirectoryItem(const DexFile& dex_file,
171 const DexFile::AnnotationsDirectoryItem* disk_annotations_item, uint32_t offset);
172 CodeItem* CreateCodeItem(
173 const DexFile& dex_file, const DexFile::CodeItem& disk_code_item, uint32_t offset);
174 ClassData* CreateClassData(const DexFile& dex_file, const uint8_t* encoded_data, uint32_t offset);
175
176 StringId* GetStringId(uint32_t index) { return StringIds()[index].get(); }
177 TypeId* GetTypeId(uint32_t index) { return TypeIds()[index].get(); }
178 ProtoId* GetProtoId(uint32_t index) { return ProtoIds()[index].get(); }
179 FieldId* GetFieldId(uint32_t index) { return FieldIds()[index].get(); }
180 MethodId* GetMethodId(uint32_t index) { return MethodIds()[index].get(); }
181 ClassDef* GetClassDef(uint32_t index) { return ClassDefs()[index].get(); }
182
183 StringId* GetStringIdOrNullPtr(uint32_t index) {
184 return index == DexFile::kDexNoIndex ? nullptr : GetStringId(index);
185 }
186 TypeId* GetTypeIdOrNullPtr(uint16_t index) {
187 return index == DexFile::kDexNoIndex16 ? nullptr : GetTypeId(index);
188 }
189
190 uint32_t StringIdsOffset() const { return string_ids_.GetOffset(); }
191 uint32_t TypeIdsOffset() const { return type_ids_.GetOffset(); }
192 uint32_t ProtoIdsOffset() const { return proto_ids_.GetOffset(); }
193 uint32_t FieldIdsOffset() const { return field_ids_.GetOffset(); }
194 uint32_t MethodIdsOffset() const { return method_ids_.GetOffset(); }
195 uint32_t ClassDefsOffset() const { return class_defs_.GetOffset(); }
196 uint32_t StringDatasOffset() const { return string_datas_.GetOffset(); }
197 uint32_t TypeListsOffset() const { return type_lists_.GetOffset(); }
Jeff Hao69b58cf2016-09-22 18:02:49 -0700198 uint32_t EncodedArrayItemsOffset() const { return encoded_array_items_.GetOffset(); }
199 uint32_t AnnotationItemsOffset() const { return annotation_items_.GetOffset(); }
200 uint32_t AnnotationSetItemsOffset() const { return annotation_set_items_.GetOffset(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700201 uint32_t AnnotationSetRefListsOffset() const { return annotation_set_ref_lists_.GetOffset(); }
Jeff Hao69b58cf2016-09-22 18:02:49 -0700202 uint32_t AnnotationsDirectoryItemsOffset() const
203 { return annotations_directory_items_.GetOffset(); }
204 uint32_t DebugInfoItemsOffset() const { return debug_info_items_.GetOffset(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700205 uint32_t CodeItemsOffset() const { return code_items_.GetOffset(); }
206 uint32_t ClassDatasOffset() const { return class_datas_.GetOffset(); }
Jeff Hao69b58cf2016-09-22 18:02:49 -0700207 uint32_t MapItemOffset() const { return map_item_offset_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700208
209 void SetStringIdsOffset(uint32_t new_offset) { string_ids_.SetOffset(new_offset); }
210 void SetTypeIdsOffset(uint32_t new_offset) { type_ids_.SetOffset(new_offset); }
211 void SetProtoIdsOffset(uint32_t new_offset) { proto_ids_.SetOffset(new_offset); }
212 void SetFieldIdsOffset(uint32_t new_offset) { field_ids_.SetOffset(new_offset); }
213 void SetMethodIdsOffset(uint32_t new_offset) { method_ids_.SetOffset(new_offset); }
214 void SetClassDefsOffset(uint32_t new_offset) { class_defs_.SetOffset(new_offset); }
215 void SetStringDatasOffset(uint32_t new_offset) { string_datas_.SetOffset(new_offset); }
216 void SetTypeListsOffset(uint32_t new_offset) { type_lists_.SetOffset(new_offset); }
Jeff Hao69b58cf2016-09-22 18:02:49 -0700217 void SetEncodedArrayItemsOffset(uint32_t new_offset)
218 { encoded_array_items_.SetOffset(new_offset); }
219 void SetAnnotationItemsOffset(uint32_t new_offset) { annotation_items_.SetOffset(new_offset); }
220 void SetAnnotationSetItemsOffset(uint32_t new_offset)
221 { annotation_set_items_.SetOffset(new_offset); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700222 void SetAnnotationSetRefListsOffset(uint32_t new_offset)
223 { annotation_set_ref_lists_.SetOffset(new_offset); }
Jeff Hao69b58cf2016-09-22 18:02:49 -0700224 void SetAnnotationsDirectoryItemsOffset(uint32_t new_offset)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700225 { annotations_directory_items_.SetOffset(new_offset); }
Jeff Hao69b58cf2016-09-22 18:02:49 -0700226 void SetDebugInfoItemsOffset(uint32_t new_offset) { debug_info_items_.SetOffset(new_offset); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700227 void SetCodeItemsOffset(uint32_t new_offset) { code_items_.SetOffset(new_offset); }
228 void SetClassDatasOffset(uint32_t new_offset) { class_datas_.SetOffset(new_offset); }
Jeff Hao69b58cf2016-09-22 18:02:49 -0700229 void SetMapItemOffset(uint32_t new_offset) { map_item_offset_ = new_offset; }
230
231 void CalculateSectionOffsets();
Jeff Hao3ab96b42016-09-09 18:35:01 -0700232
233 uint32_t StringIdsSize() const { return string_ids_.Size(); }
234 uint32_t TypeIdsSize() const { return type_ids_.Size(); }
235 uint32_t ProtoIdsSize() const { return proto_ids_.Size(); }
236 uint32_t FieldIdsSize() const { return field_ids_.Size(); }
237 uint32_t MethodIdsSize() const { return method_ids_.Size(); }
238 uint32_t ClassDefsSize() const { return class_defs_.Size(); }
Jeff Hao69b58cf2016-09-22 18:02:49 -0700239 uint32_t StringDatasSize() const { return string_datas_.Size(); }
240 uint32_t TypeListsSize() const { return type_lists_.Size(); }
241 uint32_t EncodedArrayItemsSize() const { return encoded_array_items_.Size(); }
242 uint32_t AnnotationItemsSize() const { return annotation_items_.Size(); }
243 uint32_t AnnotationSetItemsSize() const { return annotation_set_items_.Size(); }
244 uint32_t AnnotationSetRefListsSize() const { return annotation_set_ref_lists_.Size(); }
245 uint32_t AnnotationsDirectoryItemsSize() const { return annotations_directory_items_.Size(); }
246 uint32_t DebugInfoItemsSize() const { return debug_info_items_.Size(); }
247 uint32_t CodeItemsSize() const { return code_items_.Size(); }
248 uint32_t ClassDatasSize() const { return class_datas_.Size(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700249
250 private:
251 EncodedValue* ReadEncodedValue(const uint8_t** data);
252 EncodedValue* ReadEncodedValue(const uint8_t** data, uint8_t type, uint8_t length);
253 void ReadEncodedValue(const uint8_t** data, uint8_t type, uint8_t length, EncodedValue* item);
254
255 ParameterAnnotation* GenerateParameterAnnotation(const DexFile& dex_file, MethodId* method_id,
256 const DexFile::AnnotationSetRefList* annotation_set_ref_list, uint32_t offset);
257 MethodItem* GenerateMethodItem(const DexFile& dex_file, ClassDataItemIterator& cdii);
258
259 CollectionWithOffset<StringId> string_ids_;
260 CollectionWithOffset<TypeId> type_ids_;
261 CollectionWithOffset<ProtoId> proto_ids_;
262 CollectionWithOffset<FieldId> field_ids_;
263 CollectionWithOffset<MethodId> method_ids_;
264 CollectionWithOffset<ClassDef> class_defs_;
265
266 CollectionWithOffset<StringData> string_datas_;
267 CollectionWithOffset<TypeList> type_lists_;
268 CollectionWithOffset<EncodedArrayItem> encoded_array_items_;
269 CollectionWithOffset<AnnotationItem> annotation_items_;
270 CollectionWithOffset<AnnotationSetItem> annotation_set_items_;
271 CollectionWithOffset<AnnotationSetRefList> annotation_set_ref_lists_;
272 CollectionWithOffset<AnnotationsDirectoryItem> annotations_directory_items_;
273 CollectionWithOffset<DebugInfoItem> debug_info_items_;
274 CollectionWithOffset<CodeItem> code_items_;
275 CollectionWithOffset<ClassData> class_datas_;
276
Jeff Hao69b58cf2016-09-22 18:02:49 -0700277 uint32_t map_item_offset_ = 0;
278
Jeff Hao3ab96b42016-09-09 18:35:01 -0700279 DISALLOW_COPY_AND_ASSIGN(Collections);
280};
281
David Sehr7629f602016-08-07 16:01:51 -0700282class Item {
283 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700284 Item() { }
David Sehr7629f602016-08-07 16:01:51 -0700285 virtual ~Item() { }
David Sehr853a8e12016-09-01 13:03:50 -0700286
David Sehr7629f602016-08-07 16:01:51 -0700287 uint32_t GetOffset() const { return offset_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700288 uint32_t GetSize() const { return size_; }
David Sehr7629f602016-08-07 16:01:51 -0700289 void SetOffset(uint32_t offset) { offset_ = offset; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700290 void SetSize(uint32_t size) { size_ = size; }
David Sehr853a8e12016-09-01 13:03:50 -0700291
David Sehr7629f602016-08-07 16:01:51 -0700292 protected:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700293 Item(uint32_t offset, uint32_t size) : offset_(offset), size_(size) { }
294
David Sehr7629f602016-08-07 16:01:51 -0700295 uint32_t offset_ = 0;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700296 uint32_t size_ = 0;
297};
298
299class IndexedItem : public Item {
300 public:
301 IndexedItem() { }
302 virtual ~IndexedItem() { }
303
304 uint32_t GetIndex() const { return index_; }
305 void SetIndex(uint32_t index) { index_ = index; }
306
307 protected:
308 IndexedItem(uint32_t offset, uint32_t size, uint32_t index)
309 : Item(offset, size), index_(index) { }
310
311 uint32_t index_ = 0;
David Sehr7629f602016-08-07 16:01:51 -0700312};
313
314class Header : public Item {
315 public:
David Sehr853a8e12016-09-01 13:03:50 -0700316 Header(const uint8_t* magic,
317 uint32_t checksum,
318 const uint8_t* signature,
319 uint32_t endian_tag,
320 uint32_t file_size,
321 uint32_t header_size,
322 uint32_t link_size,
323 uint32_t link_offset,
324 uint32_t data_size,
325 uint32_t data_offset)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700326 : Item(0, kHeaderItemSize),
327 checksum_(checksum),
David Sehr853a8e12016-09-01 13:03:50 -0700328 endian_tag_(endian_tag),
329 file_size_(file_size),
330 header_size_(header_size),
331 link_size_(link_size),
332 link_offset_(link_offset),
333 data_size_(data_size),
334 data_offset_(data_offset) {
335 memcpy(magic_, magic, sizeof(magic_));
336 memcpy(signature_, signature, sizeof(signature_));
337 }
David Sehr7629f602016-08-07 16:01:51 -0700338 ~Header() OVERRIDE { }
339
Jeff Hao3ab96b42016-09-09 18:35:01 -0700340 static size_t ItemSize() { return kHeaderItemSize; }
341
David Sehr7629f602016-08-07 16:01:51 -0700342 const uint8_t* Magic() const { return magic_; }
343 uint32_t Checksum() const { return checksum_; }
344 const uint8_t* Signature() const { return signature_; }
345 uint32_t EndianTag() const { return endian_tag_; }
346 uint32_t FileSize() const { return file_size_; }
347 uint32_t HeaderSize() const { return header_size_; }
348 uint32_t LinkSize() const { return link_size_; }
349 uint32_t LinkOffset() const { return link_offset_; }
350 uint32_t DataSize() const { return data_size_; }
351 uint32_t DataOffset() const { return data_offset_; }
352
353 void SetChecksum(uint32_t new_checksum) { checksum_ = new_checksum; }
354 void SetSignature(const uint8_t* new_signature) {
355 memcpy(signature_, new_signature, sizeof(signature_));
356 }
357 void SetFileSize(uint32_t new_file_size) { file_size_ = new_file_size; }
358 void SetHeaderSize(uint32_t new_header_size) { header_size_ = new_header_size; }
359 void SetLinkSize(uint32_t new_link_size) { link_size_ = new_link_size; }
360 void SetLinkOffset(uint32_t new_link_offset) { link_offset_ = new_link_offset; }
361 void SetDataSize(uint32_t new_data_size) { data_size_ = new_data_size; }
362 void SetDataOffset(uint32_t new_data_offset) { data_offset_ = new_data_offset; }
363
Jeff Hao3ab96b42016-09-09 18:35:01 -0700364 Collections& GetCollections() { return collections_; }
Jeff Haoc3acfc52016-08-29 14:18:26 -0700365
David Sehr7629f602016-08-07 16:01:51 -0700366 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
367
368 private:
David Sehr7629f602016-08-07 16:01:51 -0700369 uint8_t magic_[8];
370 uint32_t checksum_;
371 uint8_t signature_[DexFile::kSha1DigestSize];
372 uint32_t endian_tag_;
373 uint32_t file_size_;
374 uint32_t header_size_;
375 uint32_t link_size_;
376 uint32_t link_offset_;
377 uint32_t data_size_;
378 uint32_t data_offset_;
379
Jeff Hao3ab96b42016-09-09 18:35:01 -0700380 Collections collections_;
381
David Sehr7629f602016-08-07 16:01:51 -0700382 DISALLOW_COPY_AND_ASSIGN(Header);
383};
384
Jeff Hao3ab96b42016-09-09 18:35:01 -0700385class StringData : public Item {
David Sehr7629f602016-08-07 16:01:51 -0700386 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700387 explicit StringData(const char* data) : data_(strdup(data)) {
Jeff Hao69b58cf2016-09-22 18:02:49 -0700388 size_ = UnsignedLeb128Size(CountModifiedUtf8Chars(data)) + strlen(data);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700389 }
David Sehr7629f602016-08-07 16:01:51 -0700390
391 const char* Data() const { return data_.get(); }
392
393 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
394
395 private:
Jeff Hao69b58cf2016-09-22 18:02:49 -0700396 UniqueCPtr<const char> data_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700397
398 DISALLOW_COPY_AND_ASSIGN(StringData);
399};
400
401class StringId : public IndexedItem {
402 public:
403 explicit StringId(StringData* string_data) : string_data_(string_data) {
404 size_ = kStringIdItemSize;
405 }
406 ~StringId() OVERRIDE { }
407
408 static size_t ItemSize() { return kStringIdItemSize; }
409
410 const char* Data() const { return string_data_->Data(); }
411 StringData* DataItem() const { return string_data_; }
412
413 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
414
415 private:
416 StringData* string_data_;
417
David Sehr7629f602016-08-07 16:01:51 -0700418 DISALLOW_COPY_AND_ASSIGN(StringId);
419};
420
Jeff Hao3ab96b42016-09-09 18:35:01 -0700421class TypeId : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700422 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700423 explicit TypeId(StringId* string_id) : string_id_(string_id) { size_ = kTypeIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700424 ~TypeId() OVERRIDE { }
425
Jeff Hao3ab96b42016-09-09 18:35:01 -0700426 static size_t ItemSize() { return kTypeIdItemSize; }
427
David Sehr7629f602016-08-07 16:01:51 -0700428 StringId* GetStringId() const { return string_id_; }
429
430 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
431
432 private:
433 StringId* string_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700434
David Sehr7629f602016-08-07 16:01:51 -0700435 DISALLOW_COPY_AND_ASSIGN(TypeId);
436};
437
David Sehr853a8e12016-09-01 13:03:50 -0700438using TypeIdVector = std::vector<const TypeId*>;
439
Jeff Hao3ab96b42016-09-09 18:35:01 -0700440class TypeList : public Item {
David Sehr7629f602016-08-07 16:01:51 -0700441 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700442 explicit TypeList(TypeIdVector* type_list) : type_list_(type_list) {
443 size_ = sizeof(uint32_t) + (type_list->size() * sizeof(uint16_t));
444 }
445 ~TypeList() OVERRIDE { }
446
447 const TypeIdVector* GetTypeList() const { return type_list_.get(); }
448
449 private:
450 std::unique_ptr<TypeIdVector> type_list_;
451
452 DISALLOW_COPY_AND_ASSIGN(TypeList);
453};
454
455class ProtoId : public IndexedItem {
456 public:
457 ProtoId(const StringId* shorty, const TypeId* return_type, TypeList* parameters)
458 : shorty_(shorty), return_type_(return_type), parameters_(parameters)
459 { size_ = kProtoIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700460 ~ProtoId() OVERRIDE { }
461
Jeff Hao3ab96b42016-09-09 18:35:01 -0700462 static size_t ItemSize() { return kProtoIdItemSize; }
463
David Sehr7629f602016-08-07 16:01:51 -0700464 const StringId* Shorty() const { return shorty_; }
465 const TypeId* ReturnType() const { return return_type_; }
Jeff Hao69b58cf2016-09-22 18:02:49 -0700466 const TypeList* Parameters() const { return parameters_; }
David Sehr7629f602016-08-07 16:01:51 -0700467
468 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
469
470 private:
471 const StringId* shorty_;
472 const TypeId* return_type_;
Jeff Hao69b58cf2016-09-22 18:02:49 -0700473 TypeList* parameters_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700474
David Sehr7629f602016-08-07 16:01:51 -0700475 DISALLOW_COPY_AND_ASSIGN(ProtoId);
476};
477
Jeff Hao3ab96b42016-09-09 18:35:01 -0700478class FieldId : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700479 public:
David Sehr853a8e12016-09-01 13:03:50 -0700480 FieldId(const TypeId* klass, const TypeId* type, const StringId* name)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700481 : class_(klass), type_(type), name_(name) { size_ = kFieldIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700482 ~FieldId() OVERRIDE { }
483
Jeff Hao3ab96b42016-09-09 18:35:01 -0700484 static size_t ItemSize() { return kFieldIdItemSize; }
485
David Sehr7629f602016-08-07 16:01:51 -0700486 const TypeId* Class() const { return class_; }
487 const TypeId* Type() const { return type_; }
488 const StringId* Name() const { return name_; }
489
490 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
491
492 private:
493 const TypeId* class_;
494 const TypeId* type_;
495 const StringId* name_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700496
David Sehr7629f602016-08-07 16:01:51 -0700497 DISALLOW_COPY_AND_ASSIGN(FieldId);
498};
499
Jeff Hao3ab96b42016-09-09 18:35:01 -0700500class MethodId : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700501 public:
David Sehr853a8e12016-09-01 13:03:50 -0700502 MethodId(const TypeId* klass, const ProtoId* proto, const StringId* name)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700503 : class_(klass), proto_(proto), name_(name) { size_ = kMethodIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700504 ~MethodId() OVERRIDE { }
505
Jeff Hao3ab96b42016-09-09 18:35:01 -0700506 static size_t ItemSize() { return kMethodIdItemSize; }
507
David Sehr7629f602016-08-07 16:01:51 -0700508 const TypeId* Class() const { return class_; }
509 const ProtoId* Proto() const { return proto_; }
510 const StringId* Name() const { return name_; }
511
512 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
513
514 private:
515 const TypeId* class_;
516 const ProtoId* proto_;
517 const StringId* name_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700518
David Sehr7629f602016-08-07 16:01:51 -0700519 DISALLOW_COPY_AND_ASSIGN(MethodId);
520};
521
522class FieldItem : public Item {
523 public:
David Sehr853a8e12016-09-01 13:03:50 -0700524 FieldItem(uint32_t access_flags, const FieldId* field_id)
525 : access_flags_(access_flags), field_id_(field_id) { }
David Sehr7629f602016-08-07 16:01:51 -0700526 ~FieldItem() OVERRIDE { }
527
528 uint32_t GetAccessFlags() const { return access_flags_; }
529 const FieldId* GetFieldId() const { return field_id_; }
530
531 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
532
533 private:
534 uint32_t access_flags_;
535 const FieldId* field_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700536
David Sehr7629f602016-08-07 16:01:51 -0700537 DISALLOW_COPY_AND_ASSIGN(FieldItem);
538};
539
David Sehr853a8e12016-09-01 13:03:50 -0700540using FieldItemVector = std::vector<std::unique_ptr<FieldItem>>;
541
David Sehr7629f602016-08-07 16:01:51 -0700542class MethodItem : public Item {
543 public:
David Sehr853a8e12016-09-01 13:03:50 -0700544 MethodItem(uint32_t access_flags, const MethodId* method_id, const CodeItem* code)
545 : access_flags_(access_flags), method_id_(method_id), code_(code) { }
David Sehr7629f602016-08-07 16:01:51 -0700546 ~MethodItem() OVERRIDE { }
547
548 uint32_t GetAccessFlags() const { return access_flags_; }
549 const MethodId* GetMethodId() const { return method_id_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700550 const CodeItem* GetCodeItem() const { return code_; }
David Sehr7629f602016-08-07 16:01:51 -0700551
552 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
553
554 private:
555 uint32_t access_flags_;
556 const MethodId* method_id_;
Jeff Hao69b58cf2016-09-22 18:02:49 -0700557 const CodeItem* code_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700558
David Sehr7629f602016-08-07 16:01:51 -0700559 DISALLOW_COPY_AND_ASSIGN(MethodItem);
560};
561
David Sehr853a8e12016-09-01 13:03:50 -0700562using MethodItemVector = std::vector<std::unique_ptr<MethodItem>>;
563
Jeff Hao3ab96b42016-09-09 18:35:01 -0700564class EncodedValue {
David Sehr7629f602016-08-07 16:01:51 -0700565 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700566 explicit EncodedValue(uint8_t type) : type_(type) { }
David Sehr7629f602016-08-07 16:01:51 -0700567
568 int8_t Type() const { return type_; }
David Sehr7629f602016-08-07 16:01:51 -0700569
Jeff Hao3ab96b42016-09-09 18:35:01 -0700570 void SetBoolean(bool z) { u_.bool_val_ = z; }
571 void SetByte(int8_t b) { u_.byte_val_ = b; }
572 void SetShort(int16_t s) { u_.short_val_ = s; }
573 void SetChar(uint16_t c) { u_.char_val_ = c; }
574 void SetInt(int32_t i) { u_.int_val_ = i; }
575 void SetLong(int64_t l) { u_.long_val_ = l; }
576 void SetFloat(float f) { u_.float_val_ = f; }
577 void SetDouble(double d) { u_.double_val_ = d; }
578 void SetStringId(StringId* string_id) { u_.string_val_ = string_id; }
579 void SetTypeId(TypeId* type_id) { u_.type_val_ = type_id; }
580 void SetFieldId(FieldId* field_id) { u_.field_val_ = field_id; }
581 void SetMethodId(MethodId* method_id) { u_.method_val_ = method_id; }
582 void SetEncodedArray(EncodedArrayItem* encoded_array) { encoded_array_.reset(encoded_array); }
583 void SetEncodedAnnotation(EncodedAnnotation* encoded_annotation)
584 { encoded_annotation_.reset(encoded_annotation); }
585
586 bool GetBoolean() const { return u_.bool_val_; }
587 int8_t GetByte() const { return u_.byte_val_; }
588 int16_t GetShort() const { return u_.short_val_; }
589 uint16_t GetChar() const { return u_.char_val_; }
590 int32_t GetInt() const { return u_.int_val_; }
591 int64_t GetLong() const { return u_.long_val_; }
592 float GetFloat() const { return u_.float_val_; }
593 double GetDouble() const { return u_.double_val_; }
594 StringId* GetStringId() const { return u_.string_val_; }
595 TypeId* GetTypeId() const { return u_.type_val_; }
596 FieldId* GetFieldId() const { return u_.field_val_; }
597 MethodId* GetMethodId() const { return u_.method_val_; }
598 EncodedArrayItem* GetEncodedArray() const { return encoded_array_.get(); }
599 EncodedAnnotation* GetEncodedAnnotation() const { return encoded_annotation_.get(); }
600
601 EncodedAnnotation* ReleaseEncodedAnnotation() { return encoded_annotation_.release(); }
David Sehr7629f602016-08-07 16:01:51 -0700602
603 private:
David Sehr7629f602016-08-07 16:01:51 -0700604 uint8_t type_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700605 union {
606 bool bool_val_;
607 int8_t byte_val_;
608 int16_t short_val_;
609 uint16_t char_val_;
610 int32_t int_val_;
611 int64_t long_val_;
612 float float_val_;
613 double double_val_;
614 StringId* string_val_;
615 TypeId* type_val_;
616 FieldId* field_val_;
617 MethodId* method_val_;
618 } u_;
619 std::unique_ptr<EncodedArrayItem> encoded_array_;
620 std::unique_ptr<EncodedAnnotation> encoded_annotation_;
621
622 DISALLOW_COPY_AND_ASSIGN(EncodedValue);
David Sehr7629f602016-08-07 16:01:51 -0700623};
624
Jeff Hao3ab96b42016-09-09 18:35:01 -0700625using EncodedValueVector = std::vector<std::unique_ptr<EncodedValue>>;
626
627class AnnotationElement {
628 public:
629 AnnotationElement(StringId* name, EncodedValue* value) : name_(name), value_(value) { }
630
631 StringId* GetName() const { return name_; }
632 EncodedValue* GetValue() const { return value_.get(); }
633
634 private:
635 StringId* name_;
636 std::unique_ptr<EncodedValue> value_;
637
638 DISALLOW_COPY_AND_ASSIGN(AnnotationElement);
639};
640
641using AnnotationElementVector = std::vector<std::unique_ptr<AnnotationElement>>;
642
643class EncodedAnnotation {
644 public:
645 EncodedAnnotation(TypeId* type, AnnotationElementVector* elements)
646 : type_(type), elements_(elements) { }
647
648 TypeId* GetType() const { return type_; }
649 AnnotationElementVector* GetAnnotationElements() const { return elements_.get(); }
650
651 private:
652 TypeId* type_;
653 std::unique_ptr<AnnotationElementVector> elements_;
654
655 DISALLOW_COPY_AND_ASSIGN(EncodedAnnotation);
656};
657
658class EncodedArrayItem : public Item {
659 public:
660 explicit EncodedArrayItem(EncodedValueVector* encoded_values)
661 : encoded_values_(encoded_values) { }
662
663 EncodedValueVector* GetEncodedValues() const { return encoded_values_.get(); }
664
665 private:
666 std::unique_ptr<EncodedValueVector> encoded_values_;
667
668 DISALLOW_COPY_AND_ASSIGN(EncodedArrayItem);
669};
David Sehr853a8e12016-09-01 13:03:50 -0700670
David Sehr7629f602016-08-07 16:01:51 -0700671class ClassData : public Item {
672 public:
David Sehr853a8e12016-09-01 13:03:50 -0700673 ClassData(FieldItemVector* static_fields,
674 FieldItemVector* instance_fields,
675 MethodItemVector* direct_methods,
676 MethodItemVector* virtual_methods)
677 : static_fields_(static_fields),
678 instance_fields_(instance_fields),
679 direct_methods_(direct_methods),
680 virtual_methods_(virtual_methods) { }
681
David Sehr7629f602016-08-07 16:01:51 -0700682 ~ClassData() OVERRIDE = default;
David Sehr853a8e12016-09-01 13:03:50 -0700683 FieldItemVector* StaticFields() { return static_fields_.get(); }
684 FieldItemVector* InstanceFields() { return instance_fields_.get(); }
685 MethodItemVector* DirectMethods() { return direct_methods_.get(); }
686 MethodItemVector* VirtualMethods() { return virtual_methods_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700687
688 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
689
690 private:
David Sehr853a8e12016-09-01 13:03:50 -0700691 std::unique_ptr<FieldItemVector> static_fields_;
692 std::unique_ptr<FieldItemVector> instance_fields_;
693 std::unique_ptr<MethodItemVector> direct_methods_;
694 std::unique_ptr<MethodItemVector> virtual_methods_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700695
David Sehr7629f602016-08-07 16:01:51 -0700696 DISALLOW_COPY_AND_ASSIGN(ClassData);
697};
698
Jeff Hao3ab96b42016-09-09 18:35:01 -0700699class ClassDef : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700700 public:
David Sehr853a8e12016-09-01 13:03:50 -0700701 ClassDef(const TypeId* class_type,
702 uint32_t access_flags,
703 const TypeId* superclass,
Jeff Hao3ab96b42016-09-09 18:35:01 -0700704 TypeList* interfaces,
David Sehr853a8e12016-09-01 13:03:50 -0700705 const StringId* source_file,
706 AnnotationsDirectoryItem* annotations,
Jeff Hao3ab96b42016-09-09 18:35:01 -0700707 EncodedArrayItem* static_values,
David Sehr853a8e12016-09-01 13:03:50 -0700708 ClassData* class_data)
709 : class_type_(class_type),
710 access_flags_(access_flags),
711 superclass_(superclass),
712 interfaces_(interfaces),
David Sehr853a8e12016-09-01 13:03:50 -0700713 source_file_(source_file),
714 annotations_(annotations),
Jeff Hao69b58cf2016-09-22 18:02:49 -0700715 class_data_(class_data),
716 static_values_(static_values) { size_ = kClassDefItemSize; }
David Sehr853a8e12016-09-01 13:03:50 -0700717
David Sehr7629f602016-08-07 16:01:51 -0700718 ~ClassDef() OVERRIDE { }
719
Jeff Hao3ab96b42016-09-09 18:35:01 -0700720 static size_t ItemSize() { return kClassDefItemSize; }
721
David Sehr7629f602016-08-07 16:01:51 -0700722 const TypeId* ClassType() const { return class_type_; }
723 uint32_t GetAccessFlags() const { return access_flags_; }
724 const TypeId* Superclass() const { return superclass_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700725 const TypeIdVector* Interfaces()
726 { return interfaces_ == nullptr ? nullptr: interfaces_->GetTypeList(); }
727 uint32_t InterfacesOffset() { return interfaces_ == nullptr ? 0 : interfaces_->GetOffset(); }
David Sehr7629f602016-08-07 16:01:51 -0700728 const StringId* SourceFile() const { return source_file_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700729 AnnotationsDirectoryItem* Annotations() const { return annotations_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700730 ClassData* GetClassData() { return class_data_; }
Jeff Hao69b58cf2016-09-22 18:02:49 -0700731 EncodedArrayItem* StaticValues() { return static_values_; }
David Sehr7629f602016-08-07 16:01:51 -0700732
Jeff Haoc3acfc52016-08-29 14:18:26 -0700733 MethodItem* GenerateMethodItem(Header& header, ClassDataItemIterator& cdii);
734
David Sehr7629f602016-08-07 16:01:51 -0700735 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
736
737 private:
738 const TypeId* class_type_;
739 uint32_t access_flags_;
Jeff Hao69b58cf2016-09-22 18:02:49 -0700740 const TypeId* superclass_; // This can be nullptr.
741 TypeList* interfaces_; // This can be nullptr.
742 const StringId* source_file_; // This can be nullptr.
743 AnnotationsDirectoryItem* annotations_; // This can be nullptr.
744 ClassData* class_data_; // This can be nullptr.
745 EncodedArrayItem* static_values_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700746
David Sehr7629f602016-08-07 16:01:51 -0700747 DISALLOW_COPY_AND_ASSIGN(ClassDef);
748};
749
Jeff Hao69b58cf2016-09-22 18:02:49 -0700750class TypeAddrPair {
David Sehr853a8e12016-09-01 13:03:50 -0700751 public:
Jeff Hao69b58cf2016-09-22 18:02:49 -0700752 TypeAddrPair(const TypeId* type_id, uint32_t address) : type_id_(type_id), address_(address) { }
David Sehr853a8e12016-09-01 13:03:50 -0700753
754 const TypeId* GetTypeId() const { return type_id_; }
755 uint32_t GetAddress() const { return address_; }
756
757 private:
758 const TypeId* type_id_;
759 uint32_t address_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700760
Jeff Hao69b58cf2016-09-22 18:02:49 -0700761 DISALLOW_COPY_AND_ASSIGN(TypeAddrPair);
762};
763
764using TypeAddrPairVector = std::vector<std::unique_ptr<const TypeAddrPair>>;
765
766class CatchHandler {
767 public:
768 explicit CatchHandler(bool catch_all, uint16_t list_offset, TypeAddrPairVector* handlers)
769 : catch_all_(catch_all), list_offset_(list_offset), handlers_(handlers) { }
770
771 bool HasCatchAll() const { return catch_all_; }
772 uint16_t GetListOffset() const { return list_offset_; }
773 TypeAddrPairVector* GetHandlers() const { return handlers_.get(); }
774
775 private:
776 bool catch_all_;
777 uint16_t list_offset_;
778 std::unique_ptr<TypeAddrPairVector> handlers_;
779
David Sehr853a8e12016-09-01 13:03:50 -0700780 DISALLOW_COPY_AND_ASSIGN(CatchHandler);
781};
782
783using CatchHandlerVector = std::vector<std::unique_ptr<const CatchHandler>>;
784
785class TryItem : public Item {
786 public:
Jeff Hao69b58cf2016-09-22 18:02:49 -0700787 TryItem(uint32_t start_addr, uint16_t insn_count, const CatchHandler* handlers)
David Sehr853a8e12016-09-01 13:03:50 -0700788 : start_addr_(start_addr), insn_count_(insn_count), handlers_(handlers) { }
789 ~TryItem() OVERRIDE { }
790
791 uint32_t StartAddr() const { return start_addr_; }
792 uint16_t InsnCount() const { return insn_count_; }
Jeff Hao69b58cf2016-09-22 18:02:49 -0700793 const CatchHandler* GetHandlers() const { return handlers_; }
David Sehr853a8e12016-09-01 13:03:50 -0700794
795 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
796
797 private:
798 uint32_t start_addr_;
799 uint16_t insn_count_;
Jeff Hao69b58cf2016-09-22 18:02:49 -0700800 const CatchHandler* handlers_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700801
David Sehr853a8e12016-09-01 13:03:50 -0700802 DISALLOW_COPY_AND_ASSIGN(TryItem);
803};
804
805using TryItemVector = std::vector<std::unique_ptr<const TryItem>>;
806
David Sehr7629f602016-08-07 16:01:51 -0700807class CodeItem : public Item {
808 public:
David Sehr853a8e12016-09-01 13:03:50 -0700809 CodeItem(uint16_t registers_size,
810 uint16_t ins_size,
811 uint16_t outs_size,
812 DebugInfoItem* debug_info,
813 uint32_t insns_size,
814 uint16_t* insns,
Jeff Hao69b58cf2016-09-22 18:02:49 -0700815 TryItemVector* tries,
816 CatchHandlerVector* handlers)
David Sehr853a8e12016-09-01 13:03:50 -0700817 : registers_size_(registers_size),
818 ins_size_(ins_size),
819 outs_size_(outs_size),
820 debug_info_(debug_info),
821 insns_size_(insns_size),
822 insns_(insns),
Jeff Hao69b58cf2016-09-22 18:02:49 -0700823 tries_(tries),
824 handlers_(handlers) { }
David Sehr853a8e12016-09-01 13:03:50 -0700825
David Sehr7629f602016-08-07 16:01:51 -0700826 ~CodeItem() OVERRIDE { }
827
828 uint16_t RegistersSize() const { return registers_size_; }
829 uint16_t InsSize() const { return ins_size_; }
830 uint16_t OutsSize() const { return outs_size_; }
David Sehr853a8e12016-09-01 13:03:50 -0700831 uint16_t TriesSize() const { return tries_ == nullptr ? 0 : tries_->size(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700832 DebugInfoItem* DebugInfo() const { return debug_info_; }
David Sehr7629f602016-08-07 16:01:51 -0700833 uint32_t InsnsSize() const { return insns_size_; }
834 uint16_t* Insns() const { return insns_.get(); }
David Sehr853a8e12016-09-01 13:03:50 -0700835 TryItemVector* Tries() const { return tries_.get(); }
Jeff Hao69b58cf2016-09-22 18:02:49 -0700836 CatchHandlerVector* Handlers() const { return handlers_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700837
838 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
839
840 private:
841 uint16_t registers_size_;
842 uint16_t ins_size_;
843 uint16_t outs_size_;
Jeff Hao69b58cf2016-09-22 18:02:49 -0700844 DebugInfoItem* debug_info_; // This can be nullptr.
David Sehr7629f602016-08-07 16:01:51 -0700845 uint32_t insns_size_;
846 std::unique_ptr<uint16_t[]> insns_;
Jeff Hao69b58cf2016-09-22 18:02:49 -0700847 std::unique_ptr<TryItemVector> tries_; // This can be nullptr.
848 std::unique_ptr<CatchHandlerVector> handlers_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700849
David Sehr7629f602016-08-07 16:01:51 -0700850 DISALLOW_COPY_AND_ASSIGN(CodeItem);
851};
852
David Sehr7629f602016-08-07 16:01:51 -0700853struct PositionInfo {
854 PositionInfo(uint32_t address, uint32_t line) : address_(address), line_(line) { }
855
856 uint32_t address_;
857 uint32_t line_;
858};
859
David Sehr853a8e12016-09-01 13:03:50 -0700860using PositionInfoVector = std::vector<std::unique_ptr<PositionInfo>>;
861
David Sehr7629f602016-08-07 16:01:51 -0700862struct LocalInfo {
David Sehr853a8e12016-09-01 13:03:50 -0700863 LocalInfo(const char* name,
864 const char* descriptor,
865 const char* signature,
866 uint32_t start_address,
867 uint32_t end_address,
868 uint16_t reg)
869 : name_(name),
870 descriptor_(descriptor),
871 signature_(signature),
872 start_address_(start_address),
873 end_address_(end_address),
874 reg_(reg) { }
David Sehr7629f602016-08-07 16:01:51 -0700875
876 std::string name_;
877 std::string descriptor_;
878 std::string signature_;
879 uint32_t start_address_;
880 uint32_t end_address_;
881 uint16_t reg_;
882};
883
David Sehr853a8e12016-09-01 13:03:50 -0700884using LocalInfoVector = std::vector<std::unique_ptr<LocalInfo>>;
885
David Sehr7629f602016-08-07 16:01:51 -0700886class DebugInfoItem : public Item {
887 public:
Jeff Hao69b58cf2016-09-22 18:02:49 -0700888 DebugInfoItem(uint32_t debug_info_size, uint8_t* debug_info)
889 : debug_info_size_(debug_info_size), debug_info_(debug_info) { }
890
891 uint32_t GetDebugInfoSize() const { return debug_info_size_; }
892 uint8_t* GetDebugInfo() const { return debug_info_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700893
David Sehr853a8e12016-09-01 13:03:50 -0700894 PositionInfoVector& GetPositionInfo() { return positions_; }
895 LocalInfoVector& GetLocalInfo() { return locals_; }
David Sehr7629f602016-08-07 16:01:51 -0700896
897 private:
Jeff Hao69b58cf2016-09-22 18:02:49 -0700898 uint32_t debug_info_size_;
899 std::unique_ptr<uint8_t[]> debug_info_;
900
David Sehr853a8e12016-09-01 13:03:50 -0700901 PositionInfoVector positions_;
902 LocalInfoVector locals_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700903
David Sehr7629f602016-08-07 16:01:51 -0700904 DISALLOW_COPY_AND_ASSIGN(DebugInfoItem);
905};
906
Jeff Hao3ab96b42016-09-09 18:35:01 -0700907class AnnotationItem : public Item {
David Sehr853a8e12016-09-01 13:03:50 -0700908 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700909 AnnotationItem(uint8_t visibility, EncodedAnnotation* annotation)
910 : visibility_(visibility), annotation_(annotation) { }
David Sehr853a8e12016-09-01 13:03:50 -0700911
912 uint8_t GetVisibility() const { return visibility_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700913 EncodedAnnotation* GetAnnotation() const { return annotation_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700914
915 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
916
917 private:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700918 uint8_t visibility_;
919 std::unique_ptr<EncodedAnnotation> annotation_;
920
921 DISALLOW_COPY_AND_ASSIGN(AnnotationItem);
922};
923
924class AnnotationSetItem : public Item {
925 public:
926 explicit AnnotationSetItem(std::vector<AnnotationItem*>* items) : items_(items) {
927 size_ = sizeof(uint32_t) + items->size() * sizeof(uint32_t);
928 }
929 ~AnnotationSetItem() OVERRIDE { }
930
931 std::vector<AnnotationItem*>* GetItems() { return items_.get(); }
932
933 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
934
935 private:
936 std::unique_ptr<std::vector<AnnotationItem*>> items_;
937
David Sehr7629f602016-08-07 16:01:51 -0700938 DISALLOW_COPY_AND_ASSIGN(AnnotationSetItem);
939};
940
Jeff Hao3ab96b42016-09-09 18:35:01 -0700941class AnnotationSetRefList : public Item {
942 public:
943 explicit AnnotationSetRefList(std::vector<AnnotationSetItem*>* items) : items_(items) {
944 size_ = sizeof(uint32_t) + items->size() * sizeof(uint32_t);
945 }
946 ~AnnotationSetRefList() OVERRIDE { }
947
948 std::vector<AnnotationSetItem*>* GetItems() { return items_.get(); }
949
950 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
951
952 private:
Jeff Hao69b58cf2016-09-22 18:02:49 -0700953 std::unique_ptr<std::vector<AnnotationSetItem*>> items_; // Elements of vector can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700954
955 DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefList);
956};
David Sehr853a8e12016-09-01 13:03:50 -0700957
958class FieldAnnotation {
959 public:
960 FieldAnnotation(FieldId* field_id, AnnotationSetItem* annotation_set_item)
961 : field_id_(field_id), annotation_set_item_(annotation_set_item) { }
962
963 FieldId* GetFieldId() const { return field_id_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700964 AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_; }
David Sehr853a8e12016-09-01 13:03:50 -0700965
966 private:
967 FieldId* field_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700968 AnnotationSetItem* annotation_set_item_;
969
David Sehr853a8e12016-09-01 13:03:50 -0700970 DISALLOW_COPY_AND_ASSIGN(FieldAnnotation);
971};
972
973using FieldAnnotationVector = std::vector<std::unique_ptr<FieldAnnotation>>;
974
975class MethodAnnotation {
976 public:
977 MethodAnnotation(MethodId* method_id, AnnotationSetItem* annotation_set_item)
978 : method_id_(method_id), annotation_set_item_(annotation_set_item) { }
979
980 MethodId* GetMethodId() const { return method_id_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700981 AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_; }
David Sehr853a8e12016-09-01 13:03:50 -0700982
983 private:
984 MethodId* method_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700985 AnnotationSetItem* annotation_set_item_;
986
David Sehr853a8e12016-09-01 13:03:50 -0700987 DISALLOW_COPY_AND_ASSIGN(MethodAnnotation);
988};
989
990using MethodAnnotationVector = std::vector<std::unique_ptr<MethodAnnotation>>;
991
992class ParameterAnnotation {
993 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700994 ParameterAnnotation(MethodId* method_id, AnnotationSetRefList* annotations)
David Sehr853a8e12016-09-01 13:03:50 -0700995 : method_id_(method_id), annotations_(annotations) { }
996
997 MethodId* GetMethodId() const { return method_id_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700998 AnnotationSetRefList* GetAnnotations() { return annotations_; }
David Sehr853a8e12016-09-01 13:03:50 -0700999
1000 private:
1001 MethodId* method_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -07001002 AnnotationSetRefList* annotations_;
1003
David Sehr853a8e12016-09-01 13:03:50 -07001004 DISALLOW_COPY_AND_ASSIGN(ParameterAnnotation);
1005};
1006
1007using ParameterAnnotationVector = std::vector<std::unique_ptr<ParameterAnnotation>>;
1008
David Sehr7629f602016-08-07 16:01:51 -07001009class AnnotationsDirectoryItem : public Item {
1010 public:
David Sehr853a8e12016-09-01 13:03:50 -07001011 AnnotationsDirectoryItem(AnnotationSetItem* class_annotation,
1012 FieldAnnotationVector* field_annotations,
1013 MethodAnnotationVector* method_annotations,
1014 ParameterAnnotationVector* parameter_annotations)
1015 : class_annotation_(class_annotation),
1016 field_annotations_(field_annotations),
1017 method_annotations_(method_annotations),
1018 parameter_annotations_(parameter_annotations) { }
David Sehr7629f602016-08-07 16:01:51 -07001019
Jeff Hao3ab96b42016-09-09 18:35:01 -07001020 AnnotationSetItem* GetClassAnnotation() const { return class_annotation_; }
David Sehr853a8e12016-09-01 13:03:50 -07001021 FieldAnnotationVector* GetFieldAnnotations() { return field_annotations_.get(); }
1022 MethodAnnotationVector* GetMethodAnnotations() { return method_annotations_.get(); }
1023 ParameterAnnotationVector* GetParameterAnnotations() { return parameter_annotations_.get(); }
David Sehr7629f602016-08-07 16:01:51 -07001024
1025 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1026
1027 private:
Jeff Hao69b58cf2016-09-22 18:02:49 -07001028 AnnotationSetItem* class_annotation_; // This can be nullptr.
1029 std::unique_ptr<FieldAnnotationVector> field_annotations_; // This can be nullptr.
1030 std::unique_ptr<MethodAnnotationVector> method_annotations_; // This can be nullptr.
1031 std::unique_ptr<ParameterAnnotationVector> parameter_annotations_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -07001032
David Sehr7629f602016-08-07 16:01:51 -07001033 DISALLOW_COPY_AND_ASSIGN(AnnotationsDirectoryItem);
1034};
1035
1036// TODO(sehr): implement MapList.
1037class MapList : public Item {
1038 public:
1039 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1040
1041 private:
1042 DISALLOW_COPY_AND_ASSIGN(MapList);
1043};
1044
1045class MapItem : public Item {
1046 public:
1047 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1048
1049 private:
1050 DISALLOW_COPY_AND_ASSIGN(MapItem);
1051};
1052
1053} // namespace dex_ir
1054} // namespace art
1055
1056#endif // ART_DEXLAYOUT_DEX_IR_H_