blob: 514d6fdc58e8c31e8b38458fa75e0abed15793ac [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"
David Sehr7629f602016-08-07 16:01:51 -070026
27namespace art {
28namespace dex_ir {
29
30// Forward declarations for classes used in containers or pointed to.
31class AnnotationsDirectoryItem;
32class AnnotationSetItem;
33class ArrayItem;
34class ClassData;
35class ClassDef;
36class CodeItem;
37class DebugInfoItem;
38class FieldId;
39class FieldItem;
40class Header;
41class MapList;
42class MapItem;
43class MethodId;
44class MethodItem;
45class ProtoId;
46class StringId;
47class TryItem;
48class TypeId;
49
50// Visitor support
51class AbstractDispatcher {
52 public:
53 AbstractDispatcher() = default;
54 virtual ~AbstractDispatcher() { }
55
56 virtual void Dispatch(Header* header) = 0;
57 virtual void Dispatch(const StringId* string_id) = 0;
58 virtual void Dispatch(const TypeId* type_id) = 0;
59 virtual void Dispatch(const ProtoId* proto_id) = 0;
60 virtual void Dispatch(const FieldId* field_id) = 0;
61 virtual void Dispatch(const MethodId* method_id) = 0;
62 virtual void Dispatch(ClassData* class_data) = 0;
63 virtual void Dispatch(ClassDef* class_def) = 0;
64 virtual void Dispatch(FieldItem* field_item) = 0;
65 virtual void Dispatch(MethodItem* method_item) = 0;
66 virtual void Dispatch(ArrayItem* array_item) = 0;
67 virtual void Dispatch(CodeItem* code_item) = 0;
68 virtual void Dispatch(TryItem* try_item) = 0;
69 virtual void Dispatch(DebugInfoItem* debug_info_item) = 0;
70 virtual void Dispatch(AnnotationSetItem* annotation_set_item) = 0;
71 virtual void Dispatch(AnnotationsDirectoryItem* annotations_directory_item) = 0;
72 virtual void Dispatch(MapList* map_list) = 0;
73 virtual void Dispatch(MapItem* map_item) = 0;
74
75 private:
76 DISALLOW_COPY_AND_ASSIGN(AbstractDispatcher);
77};
78
79// Collections become owners of the objects added by moving them into unique pointers.
80template<class T> class CollectionWithOffset {
81 public:
82 CollectionWithOffset() = default;
83 std::vector<std::unique_ptr<T>>& Collection() { return collection_; }
84 // Read-time support methods
85 void AddWithPosition(uint32_t position, T* object) {
86 collection_.push_back(std::unique_ptr<T>(object));
87 collection_.back()->SetOffset(position);
88 }
89 // Ordinary object insertion into collection.
90 void Insert(T object ATTRIBUTE_UNUSED) {
91 // TODO(sehr): add ordered insertion support.
92 UNIMPLEMENTED(FATAL) << "Insertion not ready";
93 }
94 uint32_t GetOffset() const { return offset_; }
95 void SetOffset(uint32_t new_offset) { offset_ = new_offset; }
96 uint32_t Size() const { return collection_.size(); }
97
98 private:
99 std::vector<std::unique_ptr<T>> collection_;
100 uint32_t offset_ = 0;
101 DISALLOW_COPY_AND_ASSIGN(CollectionWithOffset);
102};
103
104class Item {
105 public:
106 virtual ~Item() { }
David Sehr853a8e12016-09-01 13:03:50 -0700107
David Sehr7629f602016-08-07 16:01:51 -0700108 uint32_t GetOffset() const { return offset_; }
109 void SetOffset(uint32_t offset) { offset_ = offset; }
David Sehr853a8e12016-09-01 13:03:50 -0700110
David Sehr7629f602016-08-07 16:01:51 -0700111 protected:
112 uint32_t offset_ = 0;
113};
114
115class Header : public Item {
116 public:
David Sehr853a8e12016-09-01 13:03:50 -0700117 Header(const uint8_t* magic,
118 uint32_t checksum,
119 const uint8_t* signature,
120 uint32_t endian_tag,
121 uint32_t file_size,
122 uint32_t header_size,
123 uint32_t link_size,
124 uint32_t link_offset,
125 uint32_t data_size,
126 uint32_t data_offset)
127 : checksum_(checksum),
128 endian_tag_(endian_tag),
129 file_size_(file_size),
130 header_size_(header_size),
131 link_size_(link_size),
132 link_offset_(link_offset),
133 data_size_(data_size),
134 data_offset_(data_offset) {
135 memcpy(magic_, magic, sizeof(magic_));
136 memcpy(signature_, signature, sizeof(signature_));
137 }
David Sehr7629f602016-08-07 16:01:51 -0700138 ~Header() OVERRIDE { }
139
David Sehr7629f602016-08-07 16:01:51 -0700140 const uint8_t* Magic() const { return magic_; }
141 uint32_t Checksum() const { return checksum_; }
142 const uint8_t* Signature() const { return signature_; }
143 uint32_t EndianTag() const { return endian_tag_; }
144 uint32_t FileSize() const { return file_size_; }
145 uint32_t HeaderSize() const { return header_size_; }
146 uint32_t LinkSize() const { return link_size_; }
147 uint32_t LinkOffset() const { return link_offset_; }
148 uint32_t DataSize() const { return data_size_; }
149 uint32_t DataOffset() const { return data_offset_; }
150
151 void SetChecksum(uint32_t new_checksum) { checksum_ = new_checksum; }
152 void SetSignature(const uint8_t* new_signature) {
153 memcpy(signature_, new_signature, sizeof(signature_));
154 }
155 void SetFileSize(uint32_t new_file_size) { file_size_ = new_file_size; }
156 void SetHeaderSize(uint32_t new_header_size) { header_size_ = new_header_size; }
157 void SetLinkSize(uint32_t new_link_size) { link_size_ = new_link_size; }
158 void SetLinkOffset(uint32_t new_link_offset) { link_offset_ = new_link_offset; }
159 void SetDataSize(uint32_t new_data_size) { data_size_ = new_data_size; }
160 void SetDataOffset(uint32_t new_data_offset) { data_offset_ = new_data_offset; }
161
162 // Collections.
163 std::vector<std::unique_ptr<StringId>>& StringIds() { return string_ids_.Collection(); }
164 std::vector<std::unique_ptr<TypeId>>& TypeIds() { return type_ids_.Collection(); }
165 std::vector<std::unique_ptr<ProtoId>>& ProtoIds() { return proto_ids_.Collection(); }
166 std::vector<std::unique_ptr<FieldId>>& FieldIds() { return field_ids_.Collection(); }
167 std::vector<std::unique_ptr<MethodId>>& MethodIds() { return method_ids_.Collection(); }
168 std::vector<std::unique_ptr<ClassDef>>& ClassDefs() { return class_defs_.Collection(); }
169 uint32_t StringIdsOffset() const { return string_ids_.GetOffset(); }
170 uint32_t TypeIdsOffset() const { return type_ids_.GetOffset(); }
171 uint32_t ProtoIdsOffset() const { return proto_ids_.GetOffset(); }
172 uint32_t FieldIdsOffset() const { return field_ids_.GetOffset(); }
173 uint32_t MethodIdsOffset() const { return method_ids_.GetOffset(); }
174 uint32_t ClassDefsOffset() const { return class_defs_.GetOffset(); }
175 void SetStringIdsOffset(uint32_t new_offset) { string_ids_.SetOffset(new_offset); }
176 void SetTypeIdsOffset(uint32_t new_offset) { type_ids_.SetOffset(new_offset); }
177 void SetProtoIdsOffset(uint32_t new_offset) { proto_ids_.SetOffset(new_offset); }
178 void SetFieldIdsOffset(uint32_t new_offset) { field_ids_.SetOffset(new_offset); }
179 void SetMethodIdsOffset(uint32_t new_offset) { method_ids_.SetOffset(new_offset); }
180 void SetClassDefsOffset(uint32_t new_offset) { class_defs_.SetOffset(new_offset); }
181 uint32_t StringIdsSize() const { return string_ids_.Size(); }
182 uint32_t TypeIdsSize() const { return type_ids_.Size(); }
183 uint32_t ProtoIdsSize() const { return proto_ids_.Size(); }
184 uint32_t FieldIdsSize() const { return field_ids_.Size(); }
185 uint32_t MethodIdsSize() const { return method_ids_.Size(); }
186 uint32_t ClassDefsSize() const { return class_defs_.Size(); }
187
Jeff Haoc3acfc52016-08-29 14:18:26 -0700188 TypeId* GetTypeIdOrNullPtr(uint16_t index) {
189 return index == DexFile::kDexNoIndex16 ? nullptr : TypeIds()[index].get();
190 }
191
192 StringId* GetStringIdOrNullPtr(uint32_t index) {
193 return index == DexFile::kDexNoIndex ? nullptr : StringIds()[index].get();
194 }
195
David Sehr7629f602016-08-07 16:01:51 -0700196 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
197
198 private:
David Sehr7629f602016-08-07 16:01:51 -0700199 uint8_t magic_[8];
200 uint32_t checksum_;
201 uint8_t signature_[DexFile::kSha1DigestSize];
202 uint32_t endian_tag_;
203 uint32_t file_size_;
204 uint32_t header_size_;
205 uint32_t link_size_;
206 uint32_t link_offset_;
207 uint32_t data_size_;
208 uint32_t data_offset_;
209
210 CollectionWithOffset<StringId> string_ids_;
211 CollectionWithOffset<TypeId> type_ids_;
212 CollectionWithOffset<ProtoId> proto_ids_;
213 CollectionWithOffset<FieldId> field_ids_;
214 CollectionWithOffset<MethodId> method_ids_;
215 CollectionWithOffset<ClassDef> class_defs_;
216 DISALLOW_COPY_AND_ASSIGN(Header);
217};
218
219class StringId : public Item {
220 public:
David Sehr853a8e12016-09-01 13:03:50 -0700221 explicit StringId(const char* data) : data_(strdup(data)) { }
David Sehr7629f602016-08-07 16:01:51 -0700222 ~StringId() OVERRIDE { }
223
224 const char* Data() const { return data_.get(); }
225
226 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
227
228 private:
229 std::unique_ptr<const char> data_;
230 DISALLOW_COPY_AND_ASSIGN(StringId);
231};
232
233class TypeId : public Item {
234 public:
David Sehr853a8e12016-09-01 13:03:50 -0700235 explicit TypeId(StringId* string_id) : string_id_(string_id) { }
David Sehr7629f602016-08-07 16:01:51 -0700236 ~TypeId() OVERRIDE { }
237
238 StringId* GetStringId() const { return string_id_; }
239
240 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
241
242 private:
243 StringId* string_id_;
244 DISALLOW_COPY_AND_ASSIGN(TypeId);
245};
246
David Sehr853a8e12016-09-01 13:03:50 -0700247using TypeIdVector = std::vector<const TypeId*>;
248
David Sehr7629f602016-08-07 16:01:51 -0700249class ProtoId : public Item {
250 public:
David Sehr853a8e12016-09-01 13:03:50 -0700251 ProtoId(const StringId* shorty, const TypeId* return_type, TypeIdVector* parameters)
252 : shorty_(shorty), return_type_(return_type), parameters_(parameters) { }
David Sehr7629f602016-08-07 16:01:51 -0700253 ~ProtoId() OVERRIDE { }
254
255 const StringId* Shorty() const { return shorty_; }
256 const TypeId* ReturnType() const { return return_type_; }
David Sehr853a8e12016-09-01 13:03:50 -0700257 const std::vector<const TypeId*>& Parameters() const { return *parameters_; }
David Sehr7629f602016-08-07 16:01:51 -0700258
259 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
260
261 private:
262 const StringId* shorty_;
263 const TypeId* return_type_;
David Sehr853a8e12016-09-01 13:03:50 -0700264 std::unique_ptr<TypeIdVector> parameters_;
David Sehr7629f602016-08-07 16:01:51 -0700265 DISALLOW_COPY_AND_ASSIGN(ProtoId);
266};
267
268class FieldId : public Item {
269 public:
David Sehr853a8e12016-09-01 13:03:50 -0700270 FieldId(const TypeId* klass, const TypeId* type, const StringId* name)
271 : class_(klass), type_(type), name_(name) { }
David Sehr7629f602016-08-07 16:01:51 -0700272 ~FieldId() OVERRIDE { }
273
274 const TypeId* Class() const { return class_; }
275 const TypeId* Type() const { return type_; }
276 const StringId* Name() const { return name_; }
277
278 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
279
280 private:
281 const TypeId* class_;
282 const TypeId* type_;
283 const StringId* name_;
284 DISALLOW_COPY_AND_ASSIGN(FieldId);
285};
286
287class MethodId : public Item {
288 public:
David Sehr853a8e12016-09-01 13:03:50 -0700289 MethodId(const TypeId* klass, const ProtoId* proto, const StringId* name)
290 : class_(klass), proto_(proto), name_(name) { }
David Sehr7629f602016-08-07 16:01:51 -0700291 ~MethodId() OVERRIDE { }
292
293 const TypeId* Class() const { return class_; }
294 const ProtoId* Proto() const { return proto_; }
295 const StringId* Name() const { return name_; }
296
297 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
298
299 private:
300 const TypeId* class_;
301 const ProtoId* proto_;
302 const StringId* name_;
303 DISALLOW_COPY_AND_ASSIGN(MethodId);
304};
305
306class FieldItem : public Item {
307 public:
David Sehr853a8e12016-09-01 13:03:50 -0700308 FieldItem(uint32_t access_flags, const FieldId* field_id)
309 : access_flags_(access_flags), field_id_(field_id) { }
David Sehr7629f602016-08-07 16:01:51 -0700310 ~FieldItem() OVERRIDE { }
311
312 uint32_t GetAccessFlags() const { return access_flags_; }
313 const FieldId* GetFieldId() const { return field_id_; }
314
315 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
316
317 private:
318 uint32_t access_flags_;
319 const FieldId* field_id_;
320 DISALLOW_COPY_AND_ASSIGN(FieldItem);
321};
322
David Sehr853a8e12016-09-01 13:03:50 -0700323using FieldItemVector = std::vector<std::unique_ptr<FieldItem>>;
324
David Sehr7629f602016-08-07 16:01:51 -0700325class MethodItem : public Item {
326 public:
David Sehr853a8e12016-09-01 13:03:50 -0700327 MethodItem(uint32_t access_flags, const MethodId* method_id, const CodeItem* code)
328 : access_flags_(access_flags), method_id_(method_id), code_(code) { }
David Sehr7629f602016-08-07 16:01:51 -0700329 ~MethodItem() OVERRIDE { }
330
331 uint32_t GetAccessFlags() const { return access_flags_; }
332 const MethodId* GetMethodId() const { return method_id_; }
333 const CodeItem* GetCodeItem() const { return code_.get(); }
334
335 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
336
337 private:
338 uint32_t access_flags_;
339 const MethodId* method_id_;
340 std::unique_ptr<const CodeItem> code_;
341 DISALLOW_COPY_AND_ASSIGN(MethodItem);
342};
343
David Sehr853a8e12016-09-01 13:03:50 -0700344using MethodItemVector = std::vector<std::unique_ptr<MethodItem>>;
345
David Sehr7629f602016-08-07 16:01:51 -0700346class ArrayItem : public Item {
347 public:
348 class NameValuePair {
349 public:
David Sehr853a8e12016-09-01 13:03:50 -0700350 NameValuePair(StringId* name, ArrayItem* value)
351 : name_(name), value_(value) { }
David Sehr7629f602016-08-07 16:01:51 -0700352
353 StringId* Name() const { return name_; }
354 ArrayItem* Value() const { return value_.get(); }
355
356 private:
357 StringId* name_;
358 std::unique_ptr<ArrayItem> value_;
359 DISALLOW_COPY_AND_ASSIGN(NameValuePair);
360 };
361
David Sehr853a8e12016-09-01 13:03:50 -0700362 union PayloadUnion {
363 bool bool_val_;
364 int8_t byte_val_;
365 int16_t short_val_;
366 uint16_t char_val_;
367 int32_t int_val_;
368 int64_t long_val_;
369 float float_val_;
370 double double_val_;
371 StringId* string_val_;
372 FieldId* field_val_;
373 MethodId* method_val_;
374 std::vector<std::unique_ptr<ArrayItem>>* annotation_array_val_;
375 struct {
376 StringId* string_;
377 std::vector<std::unique_ptr<NameValuePair>>* array_;
378 } annotation_annotation_val_;
379 };
380
381 explicit ArrayItem(uint8_t type) : type_(type) { }
David Sehr7629f602016-08-07 16:01:51 -0700382 ~ArrayItem() OVERRIDE { }
383
384 int8_t Type() const { return type_; }
385 bool GetBoolean() const { return item_.bool_val_; }
386 int8_t GetByte() const { return item_.byte_val_; }
387 int16_t GetShort() const { return item_.short_val_; }
388 uint16_t GetChar() const { return item_.char_val_; }
389 int32_t GetInt() const { return item_.int_val_; }
390 int64_t GetLong() const { return item_.long_val_; }
391 float GetFloat() const { return item_.float_val_; }
392 double GetDouble() const { return item_.double_val_; }
393 StringId* GetStringId() const { return item_.string_val_; }
394 FieldId* GetFieldId() const { return item_.field_val_; }
395 MethodId* GetMethodId() const { return item_.method_val_; }
396 std::vector<std::unique_ptr<ArrayItem>>* GetAnnotationArray() const {
397 return item_.annotation_array_val_;
398 }
399 StringId* GetAnnotationAnnotationString() const {
400 return item_.annotation_annotation_val_.string_;
401 }
402 std::vector<std::unique_ptr<NameValuePair>>* GetAnnotationAnnotationNameValuePairArray() const {
403 return item_.annotation_annotation_val_.array_;
404 }
David Sehr853a8e12016-09-01 13:03:50 -0700405 // Used to construct the item union. Ugly, but necessary.
406 PayloadUnion* GetPayloadUnion() { return &item_; }
David Sehr7629f602016-08-07 16:01:51 -0700407
408 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
409
410 private:
David Sehr7629f602016-08-07 16:01:51 -0700411 uint8_t type_;
David Sehr853a8e12016-09-01 13:03:50 -0700412 PayloadUnion item_;
David Sehr7629f602016-08-07 16:01:51 -0700413 DISALLOW_COPY_AND_ASSIGN(ArrayItem);
414};
415
David Sehr853a8e12016-09-01 13:03:50 -0700416using ArrayItemVector = std::vector<std::unique_ptr<ArrayItem>>;
417
David Sehr7629f602016-08-07 16:01:51 -0700418class ClassData : public Item {
419 public:
David Sehr853a8e12016-09-01 13:03:50 -0700420 ClassData(FieldItemVector* static_fields,
421 FieldItemVector* instance_fields,
422 MethodItemVector* direct_methods,
423 MethodItemVector* virtual_methods)
424 : static_fields_(static_fields),
425 instance_fields_(instance_fields),
426 direct_methods_(direct_methods),
427 virtual_methods_(virtual_methods) { }
428
David Sehr7629f602016-08-07 16:01:51 -0700429 ~ClassData() OVERRIDE = default;
David Sehr853a8e12016-09-01 13:03:50 -0700430 FieldItemVector* StaticFields() { return static_fields_.get(); }
431 FieldItemVector* InstanceFields() { return instance_fields_.get(); }
432 MethodItemVector* DirectMethods() { return direct_methods_.get(); }
433 MethodItemVector* VirtualMethods() { return virtual_methods_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700434
435 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
436
437 private:
David Sehr853a8e12016-09-01 13:03:50 -0700438 std::unique_ptr<FieldItemVector> static_fields_;
439 std::unique_ptr<FieldItemVector> instance_fields_;
440 std::unique_ptr<MethodItemVector> direct_methods_;
441 std::unique_ptr<MethodItemVector> virtual_methods_;
David Sehr7629f602016-08-07 16:01:51 -0700442 DISALLOW_COPY_AND_ASSIGN(ClassData);
443};
444
445class ClassDef : public Item {
446 public:
David Sehr853a8e12016-09-01 13:03:50 -0700447 ClassDef(const TypeId* class_type,
448 uint32_t access_flags,
449 const TypeId* superclass,
450 TypeIdVector* interfaces,
451 uint32_t interfaces_offset,
452 const StringId* source_file,
453 AnnotationsDirectoryItem* annotations,
454 ArrayItemVector* static_values,
455 ClassData* class_data)
456 : class_type_(class_type),
457 access_flags_(access_flags),
458 superclass_(superclass),
459 interfaces_(interfaces),
460 interfaces_offset_(interfaces_offset),
461 source_file_(source_file),
462 annotations_(annotations),
463 static_values_(static_values),
464 class_data_(class_data) { }
465
David Sehr7629f602016-08-07 16:01:51 -0700466 ~ClassDef() OVERRIDE { }
467
468 const TypeId* ClassType() const { return class_type_; }
469 uint32_t GetAccessFlags() const { return access_flags_; }
470 const TypeId* Superclass() const { return superclass_; }
David Sehr853a8e12016-09-01 13:03:50 -0700471 TypeIdVector* Interfaces() { return interfaces_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700472 uint32_t InterfacesOffset() const { return interfaces_offset_; }
473 void SetInterfacesOffset(uint32_t new_offset) { interfaces_offset_ = new_offset; }
474 const StringId* SourceFile() const { return source_file_; }
475 AnnotationsDirectoryItem* Annotations() const { return annotations_.get(); }
David Sehr853a8e12016-09-01 13:03:50 -0700476 ArrayItemVector* StaticValues() { return static_values_.get(); }
477 ClassData* GetClassData() { return class_data_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700478
Jeff Haoc3acfc52016-08-29 14:18:26 -0700479 MethodItem* GenerateMethodItem(Header& header, ClassDataItemIterator& cdii);
480
David Sehr7629f602016-08-07 16:01:51 -0700481 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
482
483 private:
484 const TypeId* class_type_;
485 uint32_t access_flags_;
486 const TypeId* superclass_;
David Sehr853a8e12016-09-01 13:03:50 -0700487 std::unique_ptr<TypeIdVector> interfaces_;
David Sehr7629f602016-08-07 16:01:51 -0700488 uint32_t interfaces_offset_;
489 const StringId* source_file_;
490 std::unique_ptr<AnnotationsDirectoryItem> annotations_;
David Sehr853a8e12016-09-01 13:03:50 -0700491 std::unique_ptr<ArrayItemVector> static_values_;
492 std::unique_ptr<ClassData> class_data_;
David Sehr7629f602016-08-07 16:01:51 -0700493 DISALLOW_COPY_AND_ASSIGN(ClassDef);
494};
495
David Sehr853a8e12016-09-01 13:03:50 -0700496class CatchHandler {
497 public:
498 CatchHandler(const TypeId* type_id, uint32_t address) : type_id_(type_id), address_(address) { }
499
500 const TypeId* GetTypeId() const { return type_id_; }
501 uint32_t GetAddress() const { return address_; }
502
503 private:
504 const TypeId* type_id_;
505 uint32_t address_;
506 DISALLOW_COPY_AND_ASSIGN(CatchHandler);
507};
508
509using CatchHandlerVector = std::vector<std::unique_ptr<const CatchHandler>>;
510
511class TryItem : public Item {
512 public:
513 TryItem(uint32_t start_addr, uint16_t insn_count, CatchHandlerVector* handlers)
514 : start_addr_(start_addr), insn_count_(insn_count), handlers_(handlers) { }
515 ~TryItem() OVERRIDE { }
516
517 uint32_t StartAddr() const { return start_addr_; }
518 uint16_t InsnCount() const { return insn_count_; }
519 const CatchHandlerVector& GetHandlers() const { return *handlers_.get(); }
520
521 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
522
523 private:
524 uint32_t start_addr_;
525 uint16_t insn_count_;
526 std::unique_ptr<CatchHandlerVector> handlers_;
527 DISALLOW_COPY_AND_ASSIGN(TryItem);
528};
529
530using TryItemVector = std::vector<std::unique_ptr<const TryItem>>;
531
David Sehr7629f602016-08-07 16:01:51 -0700532class CodeItem : public Item {
533 public:
David Sehr853a8e12016-09-01 13:03:50 -0700534 CodeItem(uint16_t registers_size,
535 uint16_t ins_size,
536 uint16_t outs_size,
537 DebugInfoItem* debug_info,
538 uint32_t insns_size,
539 uint16_t* insns,
540 TryItemVector* tries)
541 : registers_size_(registers_size),
542 ins_size_(ins_size),
543 outs_size_(outs_size),
544 debug_info_(debug_info),
545 insns_size_(insns_size),
546 insns_(insns),
547 tries_(tries) { }
548
David Sehr7629f602016-08-07 16:01:51 -0700549 ~CodeItem() OVERRIDE { }
550
551 uint16_t RegistersSize() const { return registers_size_; }
552 uint16_t InsSize() const { return ins_size_; }
553 uint16_t OutsSize() const { return outs_size_; }
David Sehr853a8e12016-09-01 13:03:50 -0700554 uint16_t TriesSize() const { return tries_ == nullptr ? 0 : tries_->size(); }
David Sehr7629f602016-08-07 16:01:51 -0700555 DebugInfoItem* DebugInfo() const { return debug_info_.get(); }
556 uint32_t InsnsSize() const { return insns_size_; }
557 uint16_t* Insns() const { return insns_.get(); }
David Sehr853a8e12016-09-01 13:03:50 -0700558 TryItemVector* Tries() const { return tries_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700559
560 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
561
562 private:
563 uint16_t registers_size_;
564 uint16_t ins_size_;
565 uint16_t outs_size_;
David Sehr7629f602016-08-07 16:01:51 -0700566 std::unique_ptr<DebugInfoItem> debug_info_;
567 uint32_t insns_size_;
568 std::unique_ptr<uint16_t[]> insns_;
David Sehr853a8e12016-09-01 13:03:50 -0700569 std::unique_ptr<TryItemVector> tries_;
David Sehr7629f602016-08-07 16:01:51 -0700570 DISALLOW_COPY_AND_ASSIGN(CodeItem);
571};
572
David Sehr7629f602016-08-07 16:01:51 -0700573
574struct PositionInfo {
575 PositionInfo(uint32_t address, uint32_t line) : address_(address), line_(line) { }
576
577 uint32_t address_;
578 uint32_t line_;
579};
580
David Sehr853a8e12016-09-01 13:03:50 -0700581using PositionInfoVector = std::vector<std::unique_ptr<PositionInfo>>;
582
David Sehr7629f602016-08-07 16:01:51 -0700583struct LocalInfo {
David Sehr853a8e12016-09-01 13:03:50 -0700584 LocalInfo(const char* name,
585 const char* descriptor,
586 const char* signature,
587 uint32_t start_address,
588 uint32_t end_address,
589 uint16_t reg)
590 : name_(name),
591 descriptor_(descriptor),
592 signature_(signature),
593 start_address_(start_address),
594 end_address_(end_address),
595 reg_(reg) { }
David Sehr7629f602016-08-07 16:01:51 -0700596
597 std::string name_;
598 std::string descriptor_;
599 std::string signature_;
600 uint32_t start_address_;
601 uint32_t end_address_;
602 uint16_t reg_;
603};
604
David Sehr853a8e12016-09-01 13:03:50 -0700605using LocalInfoVector = std::vector<std::unique_ptr<LocalInfo>>;
606
David Sehr7629f602016-08-07 16:01:51 -0700607class DebugInfoItem : public Item {
608 public:
609 DebugInfoItem() = default;
610
David Sehr853a8e12016-09-01 13:03:50 -0700611 PositionInfoVector& GetPositionInfo() { return positions_; }
612 LocalInfoVector& GetLocalInfo() { return locals_; }
David Sehr7629f602016-08-07 16:01:51 -0700613
614 private:
David Sehr853a8e12016-09-01 13:03:50 -0700615 PositionInfoVector positions_;
616 LocalInfoVector locals_;
David Sehr7629f602016-08-07 16:01:51 -0700617 DISALLOW_COPY_AND_ASSIGN(DebugInfoItem);
618};
619
David Sehr853a8e12016-09-01 13:03:50 -0700620class AnnotationItem {
621 public:
622 AnnotationItem(uint8_t visibility, ArrayItem* item) : visibility_(visibility), item_(item) { }
623
624 uint8_t GetVisibility() const { return visibility_; }
625 ArrayItem* GetItem() const { return item_.get(); }
626
627 private:
628 uint8_t visibility_;
629 std::unique_ptr<ArrayItem> item_;
630 DISALLOW_COPY_AND_ASSIGN(AnnotationItem);
631};
632
633using AnnotationItemVector = std::vector<std::unique_ptr<AnnotationItem>>;
634
David Sehr7629f602016-08-07 16:01:51 -0700635class AnnotationSetItem : public Item {
636 public:
David Sehr853a8e12016-09-01 13:03:50 -0700637 explicit AnnotationSetItem(AnnotationItemVector* items) : items_(items) { }
David Sehr7629f602016-08-07 16:01:51 -0700638 ~AnnotationSetItem() OVERRIDE { }
639
David Sehr853a8e12016-09-01 13:03:50 -0700640 AnnotationItemVector* GetItems() { return items_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700641
642 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
643
644 private:
David Sehr853a8e12016-09-01 13:03:50 -0700645 std::unique_ptr<AnnotationItemVector> items_;
David Sehr7629f602016-08-07 16:01:51 -0700646 DISALLOW_COPY_AND_ASSIGN(AnnotationSetItem);
647};
648
David Sehr853a8e12016-09-01 13:03:50 -0700649using AnnotationSetItemVector = std::vector<std::unique_ptr<AnnotationSetItem>>;
650
651class FieldAnnotation {
652 public:
653 FieldAnnotation(FieldId* field_id, AnnotationSetItem* annotation_set_item)
654 : field_id_(field_id), annotation_set_item_(annotation_set_item) { }
655
656 FieldId* GetFieldId() const { return field_id_; }
657 AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_.get(); }
658
659 private:
660 FieldId* field_id_;
661 std::unique_ptr<AnnotationSetItem> annotation_set_item_;
662 DISALLOW_COPY_AND_ASSIGN(FieldAnnotation);
663};
664
665using FieldAnnotationVector = std::vector<std::unique_ptr<FieldAnnotation>>;
666
667class MethodAnnotation {
668 public:
669 MethodAnnotation(MethodId* method_id, AnnotationSetItem* annotation_set_item)
670 : method_id_(method_id), annotation_set_item_(annotation_set_item) { }
671
672 MethodId* GetMethodId() const { return method_id_; }
673 AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_.get(); }
674
675 private:
676 MethodId* method_id_;
677 std::unique_ptr<AnnotationSetItem> annotation_set_item_;
678 DISALLOW_COPY_AND_ASSIGN(MethodAnnotation);
679};
680
681using MethodAnnotationVector = std::vector<std::unique_ptr<MethodAnnotation>>;
682
683class ParameterAnnotation {
684 public:
685 ParameterAnnotation(MethodId* method_id, AnnotationSetItemVector* annotations)
686 : method_id_(method_id), annotations_(annotations) { }
687
688 MethodId* GetMethodId() const { return method_id_; }
689 AnnotationSetItemVector* GetAnnotations() { return annotations_.get(); }
690
691 private:
692 MethodId* method_id_;
693 std::unique_ptr<AnnotationSetItemVector> annotations_;
694 DISALLOW_COPY_AND_ASSIGN(ParameterAnnotation);
695};
696
697using ParameterAnnotationVector = std::vector<std::unique_ptr<ParameterAnnotation>>;
698
David Sehr7629f602016-08-07 16:01:51 -0700699class AnnotationsDirectoryItem : public Item {
700 public:
David Sehr853a8e12016-09-01 13:03:50 -0700701 AnnotationsDirectoryItem(AnnotationSetItem* class_annotation,
702 FieldAnnotationVector* field_annotations,
703 MethodAnnotationVector* method_annotations,
704 ParameterAnnotationVector* parameter_annotations)
705 : class_annotation_(class_annotation),
706 field_annotations_(field_annotations),
707 method_annotations_(method_annotations),
708 parameter_annotations_(parameter_annotations) { }
David Sehr7629f602016-08-07 16:01:51 -0700709
710 AnnotationSetItem* GetClassAnnotation() const { return class_annotation_.get(); }
David Sehr853a8e12016-09-01 13:03:50 -0700711 FieldAnnotationVector* GetFieldAnnotations() { return field_annotations_.get(); }
712 MethodAnnotationVector* GetMethodAnnotations() { return method_annotations_.get(); }
713 ParameterAnnotationVector* GetParameterAnnotations() { return parameter_annotations_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700714
715 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
716
717 private:
718 std::unique_ptr<AnnotationSetItem> class_annotation_;
David Sehr853a8e12016-09-01 13:03:50 -0700719 std::unique_ptr<FieldAnnotationVector> field_annotations_;
720 std::unique_ptr<MethodAnnotationVector> method_annotations_;
721 std::unique_ptr<ParameterAnnotationVector> parameter_annotations_;
David Sehr7629f602016-08-07 16:01:51 -0700722 DISALLOW_COPY_AND_ASSIGN(AnnotationsDirectoryItem);
723};
724
725// TODO(sehr): implement MapList.
726class MapList : public Item {
727 public:
728 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
729
730 private:
731 DISALLOW_COPY_AND_ASSIGN(MapList);
732};
733
734class MapItem : public Item {
735 public:
736 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
737
738 private:
739 DISALLOW_COPY_AND_ASSIGN(MapItem);
740};
741
742} // namespace dex_ir
743} // namespace art
744
745#endif // ART_DEXLAYOUT_DEX_IR_H_