blob: 1951af500587aeba8bab2bb7b80e9219614e70bf [file] [log] [blame]
Carl Shapiro1fb86202011-06-27 17:43:13 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2
3#include "src/dex_file.h"
4#include "src/heap.h"
5#include "src/globals.h"
6#include "src/logging.h"
7#include "src/object.h"
8#include "src/raw_dex_file.h"
9
10namespace art {
11
12DexFile* DexFile::Open(const char* filename) {
13 RawDexFile* raw = RawDexFile::Open(filename);
14 if (raw == NULL) {
15 return NULL;
16 }
17 DexFile* dex_file = new DexFile(raw);
18 dex_file->Init();
19 return dex_file;
20}
21
22DexFile::~DexFile() {
23 delete raw_;
24 delete[] strings_;
25 delete[] classes_;
26 delete[] methods_;
27 delete[] fields_;
28}
29
30void DexFile::Init() {
31 num_strings_ = raw_->NumStringIds();
32 strings_ = new String*[num_strings_];
33
34 num_classes_ = raw_->NumTypeIds();
35 classes_ = new Class*[num_classes_];
36
37 num_methods_ = raw_->NumMethodIds();
38 methods_ = new Method*[num_methods_];
39
40 num_fields_ = raw_->NumFieldIds();
41 fields_ = new Field*[num_fields_];
42}
43
44Class* DexFile::LoadClass(const char* descriptor) {
45 const RawDexFile::ClassDef* class_def = raw_->FindClassDef(descriptor);
46 if (class_def == NULL) {
47 return NULL;
48 } else {
49 return LoadClass(*class_def);
50 }
51}
52
53Class* DexFile::LoadClass(const RawDexFile::ClassDef& class_def) {
54 const byte* class_data = raw_->GetClassData(class_def);
Carl Shapiro3ee755d2011-06-28 12:11:04 -070055 RawDexFile::ClassDataHeader header = raw_->ReadClassDataHeader(&class_data);
Carl Shapiro1fb86202011-06-27 17:43:13 -070056
57 const char* descriptor = raw_->GetClassDescriptor(class_def);
58 CHECK(descriptor != NULL);
59
60 // Allocate storage for the new class object.
61 size_t size = Class::Size(header.static_fields_size_);
62 Class* klass = Heap::AllocClass(size);
Carl Shapiro3ee755d2011-06-28 12:11:04 -070063 CHECK(klass != NULL); // TODO: throw an OOME
Carl Shapiro1fb86202011-06-27 17:43:13 -070064
Carl Shapiro3ee755d2011-06-28 12:11:04 -070065 klass->klass_ = NULL; // TODO
Carl Shapiro1fb86202011-06-27 17:43:13 -070066 klass->descriptor_ = descriptor;
67 klass->access_flags_ = class_def.access_flags_;
68 klass->class_loader_ = NULL; // TODO
69 klass->dex_file_ = this;
70 klass->primitive_type_ = Class::kPrimNot;
71 klass->status_ = Class::kClassIdx;
72
73 klass->super_ = reinterpret_cast<Class*>(class_def.superclass_idx_);
74
Carl Shapiro3ee755d2011-06-28 12:11:04 -070075 klass->num_sfields_ = header.static_fields_size_;
76 klass->num_ifields_ = header.instance_fields_size_;
77 klass->num_dmethods_ = header.direct_methods_size_;
78 klass->num_vmethods_ = header.virtual_methods_size_;
79
80 klass->source_file_ = raw_->dexGetSourceFile(class_def);
81
Carl Shapiro1fb86202011-06-27 17:43:13 -070082 // Load class interfaces.
Carl Shapiro3ee755d2011-06-28 12:11:04 -070083 LoadInterfaces(class_def, klass);
Carl Shapiro1fb86202011-06-27 17:43:13 -070084
85 // Load static fields.
Carl Shapiro3ee755d2011-06-28 12:11:04 -070086 if (klass->num_sfields_ != 0) {
87 uint32_t last_idx = 0;
88 for (size_t i = 0; i < klass->num_sfields_; ++i) {
89 RawDexFile::Field raw_field;
90 raw_->dexReadClassDataField(&class_data, &raw_field, &last_idx);
91 LoadField(klass, raw_field, &klass->sfields_[i]);
Carl Shapiro1fb86202011-06-27 17:43:13 -070092 }
93 }
94
95 // Load instance fields.
Carl Shapiro3ee755d2011-06-28 12:11:04 -070096 if (klass->num_ifields_ != 0) {
97 // TODO: append instance fields to class object
98 klass->ifields_ = new IField[klass->num_ifields_];
99 uint32_t last_idx = 0;
100 for (size_t i = 0; i < klass->num_ifields_; ++i) {
101 RawDexFile::Field raw_field;
102 raw_->dexReadClassDataField(&class_data, &raw_field, &last_idx);
103 LoadField(klass, raw_field, &klass->ifields_[i]);
Carl Shapiro1fb86202011-06-27 17:43:13 -0700104 }
105 }
106
107 // Load direct methods.
Carl Shapiro3ee755d2011-06-28 12:11:04 -0700108 if (klass->num_dmethods_ != 0) {
109 // TODO: append direct methods to class object
110 klass->dmethods_ = new Method[klass->num_dmethods_];
111 uint32_t last_idx = 0;
112 for (size_t i = 0; i < klass->num_dmethods_; ++i) {
113 RawDexFile::Method raw_method;
114 raw_->dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
115 LoadMethod(klass, raw_method, &klass->dmethods_[i]);
116 // TODO: register maps
117 }
118 }
Carl Shapiro1fb86202011-06-27 17:43:13 -0700119
120 // Load virtual methods.
Carl Shapiro3ee755d2011-06-28 12:11:04 -0700121 if (klass->num_vmethods_ != 0) {
122 // TODO: append virtual methods to class object
123 klass->vmethods_ = new Method[klass->num_vmethods_];
124 memset(klass->vmethods_, 0xff, sizeof(Method));
125 uint32_t last_idx = 0;
126 for (size_t i = 0; i < klass->num_vmethods_; ++i) {
127 RawDexFile::Method raw_method;
128 raw_->dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
129 LoadMethod(klass, raw_method, &klass->vmethods_[i]);
130 // TODO: register maps
131 }
132 }
Carl Shapiro1fb86202011-06-27 17:43:13 -0700133
134 return klass;
135}
136
Carl Shapiro3ee755d2011-06-28 12:11:04 -0700137void DexFile::LoadInterfaces(const RawDexFile::ClassDef& class_def,
138 Class* klass) {
Carl Shapiro1fb86202011-06-27 17:43:13 -0700139 const RawDexFile::TypeList* list = raw_->GetInterfacesList(class_def);
140 if (list != NULL) {
141 klass->interface_count_ = list->Size();
142 klass->interfaces_ = new Class*[list->Size()];
143 for (size_t i = 0; i < list->Size(); ++i) {
144 const RawDexFile::TypeItem& type_item = list->GetTypeItem(i);
145 klass->interfaces_[i] = reinterpret_cast<Class*>(type_item.type_idx_);
146 }
147 }
148}
149
Carl Shapiro3ee755d2011-06-28 12:11:04 -0700150void DexFile::LoadField(Class* klass, const RawDexFile::Field& src,
151 Field* dst) {
152 const RawDexFile::FieldId& field_id = raw_->GetFieldId(src.field_idx_);
153 dst->klass_ = klass;
154 dst->name_ = raw_->dexStringById(field_id.name_idx_);
155 dst->signature_ = raw_->dexStringByTypeIdx(field_id.type_idx_);
156 dst->access_flags_ = src.access_flags_;
Carl Shapiro1fb86202011-06-27 17:43:13 -0700157}
158
Carl Shapiro3ee755d2011-06-28 12:11:04 -0700159void DexFile::LoadMethod(Class* klass, const RawDexFile::Method& src,
Carl Shapiro1fb86202011-06-27 17:43:13 -0700160 Method* dst) {
Carl Shapiro3ee755d2011-06-28 12:11:04 -0700161 const RawDexFile::MethodId& method_id = raw_->GetMethodId(src.method_idx_);
162 dst->klass_ = klass;
163 dst->name_ = raw_->dexStringById(method_id.name_idx_);
164 dst->dex_file_ = this;
165 dst->proto_idx_ = method_id.proto_idx_;
166 dst->shorty_ = raw_->GetShorty(method_id.proto_idx_);
167 dst->access_flags_ = src.access_flags_;
168
169 // TODO: check for finalize method
170
171 const RawDexFile::Code* code_item = raw_->GetCode(src);
172 if (code_item != NULL) {
173 dst->num_registers_ = code_item->registers_size_;
174 dst->num_ins_ = code_item->ins_size_;
175 dst->num_outs_ = code_item->outs_size_;
176 dst->insns_ = code_item->insns_;
177 } else {
178 uint16_t num_args = dst->NumArgRegisters();
179 if (!dst->IsStatic()) {
180 ++num_args;
181 }
182 dst->num_registers_ = dst->num_ins_ + num_args;
183 // TODO: native methods
184 }
Carl Shapiro1fb86202011-06-27 17:43:13 -0700185}
186
Carl Shapiro1fb86202011-06-27 17:43:13 -0700187} // namespace art