blob: bb016b064e8817761ac6d711e5bb0eb2ee23b860 [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
Carl Shapiro80d4dde2011-06-28 16:24:07 -070012DexFile* DexFile::OpenFile(const char* filename) {
13 RawDexFile* raw = RawDexFile::OpenFile(filename);
14 return Open(raw);
15}
16
17DexFile* DexFile::OpenBase64(const char* base64) {
18 RawDexFile* raw = RawDexFile::OpenBase64(base64);
19 return Open(raw);
20}
21
22DexFile* DexFile::Open(RawDexFile* raw) {
Carl Shapiro1fb86202011-06-27 17:43:13 -070023 if (raw == NULL) {
24 return NULL;
25 }
26 DexFile* dex_file = new DexFile(raw);
27 dex_file->Init();
28 return dex_file;
29}
30
31DexFile::~DexFile() {
Carl Shapiro1fb86202011-06-27 17:43:13 -070032 delete[] strings_;
33 delete[] classes_;
34 delete[] methods_;
35 delete[] fields_;
36}
37
38void DexFile::Init() {
39 num_strings_ = raw_->NumStringIds();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070040 strings_ = new String*[num_strings_]();
Carl Shapiro1fb86202011-06-27 17:43:13 -070041
42 num_classes_ = raw_->NumTypeIds();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070043 classes_ = new Class*[num_classes_]();
Carl Shapiro1fb86202011-06-27 17:43:13 -070044
45 num_methods_ = raw_->NumMethodIds();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070046 methods_ = new Method*[num_methods_]();
Carl Shapiro1fb86202011-06-27 17:43:13 -070047
48 num_fields_ = raw_->NumFieldIds();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070049 fields_ = new Field*[num_fields_]();
Carl Shapiro1fb86202011-06-27 17:43:13 -070050}
51
52Class* DexFile::LoadClass(const char* descriptor) {
53 const RawDexFile::ClassDef* class_def = raw_->FindClassDef(descriptor);
54 if (class_def == NULL) {
55 return NULL;
56 } else {
57 return LoadClass(*class_def);
58 }
59}
60
61Class* DexFile::LoadClass(const RawDexFile::ClassDef& class_def) {
62 const byte* class_data = raw_->GetClassData(class_def);
Carl Shapiro3ee755d2011-06-28 12:11:04 -070063 RawDexFile::ClassDataHeader header = raw_->ReadClassDataHeader(&class_data);
Carl Shapiro1fb86202011-06-27 17:43:13 -070064
65 const char* descriptor = raw_->GetClassDescriptor(class_def);
66 CHECK(descriptor != NULL);
67
68 // Allocate storage for the new class object.
69 size_t size = Class::Size(header.static_fields_size_);
70 Class* klass = Heap::AllocClass(size);
Carl Shapiro3ee755d2011-06-28 12:11:04 -070071 CHECK(klass != NULL); // TODO: throw an OOME
Carl Shapiro1fb86202011-06-27 17:43:13 -070072
Carl Shapiro3ee755d2011-06-28 12:11:04 -070073 klass->klass_ = NULL; // TODO
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070074 klass->descriptor_.set(descriptor);
75 klass->descriptor_alloc_ = NULL;
Carl Shapiro1fb86202011-06-27 17:43:13 -070076 klass->access_flags_ = class_def.access_flags_;
77 klass->class_loader_ = NULL; // TODO
78 klass->dex_file_ = this;
79 klass->primitive_type_ = Class::kPrimNot;
Carl Shapiro894d0fa2011-06-30 14:48:49 -070080 klass->status_ = Class::kStatusIdx;
Carl Shapiro1fb86202011-06-27 17:43:13 -070081
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070082 klass->super_class_ = NULL;
83 klass->super_class_idx_ = class_def.superclass_idx_;
Carl Shapiro1fb86202011-06-27 17:43:13 -070084
Carl Shapiro3ee755d2011-06-28 12:11:04 -070085 klass->num_sfields_ = header.static_fields_size_;
86 klass->num_ifields_ = header.instance_fields_size_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070087 klass->num_direct_methods_ = header.direct_methods_size_;
88 klass->num_virtual_methods_ = header.virtual_methods_size_;
Carl Shapiro3ee755d2011-06-28 12:11:04 -070089
90 klass->source_file_ = raw_->dexGetSourceFile(class_def);
91
Carl Shapiro1fb86202011-06-27 17:43:13 -070092 // Load class interfaces.
Carl Shapiro3ee755d2011-06-28 12:11:04 -070093 LoadInterfaces(class_def, klass);
Carl Shapiro1fb86202011-06-27 17:43:13 -070094
95 // Load static fields.
Carl Shapiro3ee755d2011-06-28 12:11:04 -070096 if (klass->num_sfields_ != 0) {
97 uint32_t last_idx = 0;
98 for (size_t i = 0; i < klass->num_sfields_; ++i) {
99 RawDexFile::Field raw_field;
100 raw_->dexReadClassDataField(&class_data, &raw_field, &last_idx);
101 LoadField(klass, raw_field, &klass->sfields_[i]);
Carl Shapiro1fb86202011-06-27 17:43:13 -0700102 }
103 }
104
105 // Load instance fields.
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700106 if (klass->NumInstanceFields() != 0) {
Carl Shapiro3ee755d2011-06-28 12:11:04 -0700107 // TODO: append instance fields to class object
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700108 klass->ifields_ = new InstanceField[klass->NumInstanceFields()];
Carl Shapiro3ee755d2011-06-28 12:11:04 -0700109 uint32_t last_idx = 0;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700110 for (size_t i = 0; i < klass->NumInstanceFields(); ++i) {
Carl Shapiro3ee755d2011-06-28 12:11:04 -0700111 RawDexFile::Field raw_field;
112 raw_->dexReadClassDataField(&class_data, &raw_field, &last_idx);
113 LoadField(klass, raw_field, &klass->ifields_[i]);
Carl Shapiro1fb86202011-06-27 17:43:13 -0700114 }
115 }
116
117 // Load direct methods.
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700118 if (klass->NumDirectMethods() != 0) {
Carl Shapiro3ee755d2011-06-28 12:11:04 -0700119 // TODO: append direct methods to class object
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700120 klass->direct_methods_ = new Method[klass->NumDirectMethods()];
Carl Shapiro3ee755d2011-06-28 12:11:04 -0700121 uint32_t last_idx = 0;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700122 for (size_t i = 0; i < klass->NumDirectMethods(); ++i) {
Carl Shapiro3ee755d2011-06-28 12:11:04 -0700123 RawDexFile::Method raw_method;
124 raw_->dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700125 LoadMethod(klass, raw_method, klass->GetDirectMethod(i));
Carl Shapiro3ee755d2011-06-28 12:11:04 -0700126 // TODO: register maps
127 }
128 }
Carl Shapiro1fb86202011-06-27 17:43:13 -0700129
130 // Load virtual methods.
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700131 if (klass->NumVirtualMethods() != 0) {
Carl Shapiro3ee755d2011-06-28 12:11:04 -0700132 // TODO: append virtual methods to class object
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700133 klass->virtual_methods_ = new Method[klass->NumVirtualMethods()];
134 memset(klass->virtual_methods_, 0xff, sizeof(Method));
Carl Shapiro3ee755d2011-06-28 12:11:04 -0700135 uint32_t last_idx = 0;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700136 for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
Carl Shapiro3ee755d2011-06-28 12:11:04 -0700137 RawDexFile::Method raw_method;
138 raw_->dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700139 LoadMethod(klass, raw_method, klass->GetVirtualMethod(i));
Carl Shapiro3ee755d2011-06-28 12:11:04 -0700140 // TODO: register maps
141 }
142 }
Carl Shapiro1fb86202011-06-27 17:43:13 -0700143
144 return klass;
145}
146
Carl Shapiro3ee755d2011-06-28 12:11:04 -0700147void DexFile::LoadInterfaces(const RawDexFile::ClassDef& class_def,
148 Class* klass) {
Carl Shapiro1fb86202011-06-27 17:43:13 -0700149 const RawDexFile::TypeList* list = raw_->GetInterfacesList(class_def);
150 if (list != NULL) {
151 klass->interface_count_ = list->Size();
152 klass->interfaces_ = new Class*[list->Size()];
153 for (size_t i = 0; i < list->Size(); ++i) {
154 const RawDexFile::TypeItem& type_item = list->GetTypeItem(i);
155 klass->interfaces_[i] = reinterpret_cast<Class*>(type_item.type_idx_);
156 }
157 }
158}
159
Carl Shapiro3ee755d2011-06-28 12:11:04 -0700160void DexFile::LoadField(Class* klass, const RawDexFile::Field& src,
161 Field* dst) {
162 const RawDexFile::FieldId& field_id = raw_->GetFieldId(src.field_idx_);
163 dst->klass_ = klass;
164 dst->name_ = raw_->dexStringById(field_id.name_idx_);
165 dst->signature_ = raw_->dexStringByTypeIdx(field_id.type_idx_);
166 dst->access_flags_ = src.access_flags_;
Carl Shapiro1fb86202011-06-27 17:43:13 -0700167}
168
Carl Shapiro3ee755d2011-06-28 12:11:04 -0700169void DexFile::LoadMethod(Class* klass, const RawDexFile::Method& src,
Carl Shapiro1fb86202011-06-27 17:43:13 -0700170 Method* dst) {
Carl Shapiro3ee755d2011-06-28 12:11:04 -0700171 const RawDexFile::MethodId& method_id = raw_->GetMethodId(src.method_idx_);
172 dst->klass_ = klass;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700173 dst->name_.set(raw_->dexStringById(method_id.name_idx_));
Carl Shapiro3ee755d2011-06-28 12:11:04 -0700174 dst->dex_file_ = this;
175 dst->proto_idx_ = method_id.proto_idx_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700176 dst->shorty_.set(raw_->GetShorty(method_id.proto_idx_));
Carl Shapiro3ee755d2011-06-28 12:11:04 -0700177 dst->access_flags_ = src.access_flags_;
178
179 // TODO: check for finalize method
180
181 const RawDexFile::Code* code_item = raw_->GetCode(src);
182 if (code_item != NULL) {
183 dst->num_registers_ = code_item->registers_size_;
184 dst->num_ins_ = code_item->ins_size_;
185 dst->num_outs_ = code_item->outs_size_;
186 dst->insns_ = code_item->insns_;
187 } else {
188 uint16_t num_args = dst->NumArgRegisters();
189 if (!dst->IsStatic()) {
190 ++num_args;
191 }
192 dst->num_registers_ = dst->num_ins_ + num_args;
193 // TODO: native methods
194 }
Carl Shapiro1fb86202011-06-27 17:43:13 -0700195}
196
Carl Shapiro1fb86202011-06-27 17:43:13 -0700197} // namespace art