summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/class_linker.cc178
-rw-r--r--src/class_linker.h11
-rw-r--r--src/class_linker_test.cc90
-rw-r--r--src/common_test.h89
-rw-r--r--src/dex_file.cc143
-rw-r--r--src/dex_file.h10
-rw-r--r--src/dex_file_test.cc47
-rw-r--r--src/heap.h6
-rw-r--r--src/object.cc8
-rw-r--r--src/object.h6
-rw-r--r--src/object_test.cc73
-rw-r--r--src/raw_dex_file.cc6
-rw-r--r--src/raw_dex_file.h8
-rw-r--r--src/raw_dex_file_test.cc24
14 files changed, 380 insertions, 319 deletions
diff --git a/src/class_linker.cc b/src/class_linker.cc
index cf72a11..5b50113 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -20,10 +20,11 @@
namespace art {
void ClassLinker::Init() {
- // Allocate and partially initialize the class Class. This object
- // will complete its initialization when its definition is loaded.
- java_lang_Class_ = Heap::AllocClass();
- java_lang_Class_->super_class_ = java_lang_Class_;
+ // Allocate and partially initialize the Object and Class classes.
+ // Initialization will be completed when the definitions are loaded.
+ java_lang_Object_ = Heap::AllocClass(NULL);
+ java_lang_Object_->descriptor_ = "Ljava/lang/Object;";
+ java_lang_Class_ = Heap::AllocClass(NULL);
java_lang_Class_->descriptor_ = "Ljava/lang/Class;";
// Allocate and initialize the primitive type classes.
@@ -56,12 +57,16 @@ Class* ClassLinker::FindClass(const char* descriptor,
}
}
// Load the class from the dex file.
- if (!strcmp(descriptor, "Ljava/lang/Class;")) {
+ if (!strcmp(descriptor, "Ljava/lang/Object;")) {
+ klass = java_lang_Object_;
+ klass->dex_file_ = dex_file;
+ } else if (!strcmp(descriptor, "Ljava/lang/Class;")) {
klass = java_lang_Class_;
+ klass->dex_file_ = dex_file;
} else {
- klass = Heap::AllocClass();
+ klass = Heap::AllocClass(dex_file);
}
- bool is_loaded = dex_file->LoadClass(descriptor, klass);
+ bool is_loaded = LoadClass(descriptor, klass);
if (!is_loaded) {
// TODO: this occurs only when a dex file is provided.
LG << "Class not found"; // TODO: NoClassDefFoundError
@@ -116,6 +121,153 @@ Class* ClassLinker::FindClass(const char* descriptor,
return klass;
}
+bool ClassLinker::LoadClass(const char* descriptor, Class* klass) {
+ const RawDexFile* raw = klass->GetDexFile()->GetRaw();
+ const RawDexFile::ClassDef* class_def = raw->FindClassDef(descriptor);
+ if (class_def == NULL) {
+ return false;
+ } else {
+ return LoadClass(*class_def, klass);
+ }
+}
+
+bool ClassLinker::LoadClass(const RawDexFile::ClassDef& class_def, Class* klass) {
+ CHECK(klass != NULL);
+ CHECK(klass->dex_file_ != NULL);
+ const RawDexFile* raw = klass->GetDexFile()->GetRaw();
+ const byte* class_data = raw->GetClassData(class_def);
+ RawDexFile::ClassDataHeader header = raw->ReadClassDataHeader(&class_data);
+
+ const char* descriptor = raw->GetClassDescriptor(class_def);
+ CHECK(descriptor != NULL);
+
+ klass->klass_ = java_lang_Class_;
+ klass->descriptor_.set(descriptor);
+ klass->descriptor_alloc_ = NULL;
+ klass->access_flags_ = class_def.access_flags_;
+ klass->class_loader_ = NULL; // TODO
+ klass->primitive_type_ = Class::kPrimNot;
+ klass->status_ = Class::kStatusIdx;
+
+ klass->super_class_ = NULL;
+ klass->super_class_idx_ = class_def.superclass_idx_;
+
+ klass->num_sfields_ = header.static_fields_size_;
+ klass->num_ifields_ = header.instance_fields_size_;
+ klass->num_direct_methods_ = header.direct_methods_size_;
+ klass->num_virtual_methods_ = header.virtual_methods_size_;
+
+ klass->source_file_ = raw->dexGetSourceFile(class_def);
+
+ // Load class interfaces.
+ LoadInterfaces(class_def, klass);
+
+ // Load static fields.
+ if (klass->num_sfields_ != 0) {
+ // TODO: allocate on the object heap.
+ klass->sfields_ = new StaticField[klass->NumStaticFields()]();
+ uint32_t last_idx = 0;
+ for (size_t i = 0; i < klass->num_sfields_; ++i) {
+ RawDexFile::Field raw_field;
+ raw->dexReadClassDataField(&class_data, &raw_field, &last_idx);
+ LoadField(klass, raw_field, &klass->sfields_[i]);
+ }
+ }
+
+ // Load instance fields.
+ if (klass->NumInstanceFields() != 0) {
+ // TODO: allocate on the object heap.
+ klass->ifields_ = new InstanceField[klass->NumInstanceFields()]();
+ uint32_t last_idx = 0;
+ for (size_t i = 0; i < klass->NumInstanceFields(); ++i) {
+ RawDexFile::Field raw_field;
+ raw->dexReadClassDataField(&class_data, &raw_field, &last_idx);
+ LoadField(klass, raw_field, klass->GetInstanceField(i));
+ }
+ }
+
+ // Load direct methods.
+ if (klass->NumDirectMethods() != 0) {
+ // TODO: append direct methods to class object
+ klass->direct_methods_ = new Method[klass->NumDirectMethods()]();
+ uint32_t last_idx = 0;
+ for (size_t i = 0; i < klass->NumDirectMethods(); ++i) {
+ RawDexFile::Method raw_method;
+ raw->dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
+ LoadMethod(klass, raw_method, klass->GetDirectMethod(i));
+ // TODO: register maps
+ }
+ }
+
+ // Load virtual methods.
+ if (klass->NumVirtualMethods() != 0) {
+ // TODO: append virtual methods to class object
+ klass->virtual_methods_ = new Method[klass->NumVirtualMethods()]();
+ uint32_t last_idx = 0;
+ for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
+ RawDexFile::Method raw_method;
+ raw->dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
+ LoadMethod(klass, raw_method, klass->GetVirtualMethod(i));
+ // TODO: register maps
+ }
+ }
+
+ return klass;
+}
+
+void ClassLinker::LoadInterfaces(const RawDexFile::ClassDef& class_def,
+ Class* klass) {
+ const RawDexFile* raw = klass->GetDexFile()->GetRaw();
+ const RawDexFile::TypeList* list = raw->GetInterfacesList(class_def);
+ if (list != NULL) {
+ klass->interface_count_ = list->Size();
+ // TODO: allocate the interfaces array on the object heap.
+ klass->interfaces_ = new Class*[list->Size()]();
+ for (size_t i = 0; i < list->Size(); ++i) {
+ const RawDexFile::TypeItem& type_item = list->GetTypeItem(i);
+ klass->interfaces_[i] = reinterpret_cast<Class*>(type_item.type_idx_);
+ }
+ }
+}
+
+void ClassLinker::LoadField(Class* klass, const RawDexFile::Field& src,
+ Field* dst) {
+ const RawDexFile* raw = klass->GetDexFile()->GetRaw();
+ const RawDexFile::FieldId& field_id = raw->GetFieldId(src.field_idx_);
+ dst->klass_ = klass;
+ dst->name_ = raw->dexStringById(field_id.name_idx_);
+ dst->signature_ = raw->dexStringByTypeIdx(field_id.type_idx_);
+ dst->access_flags_ = src.access_flags_;
+}
+
+void ClassLinker::LoadMethod(Class* klass, const RawDexFile::Method& src,
+ Method* dst) {
+ const RawDexFile* raw = klass->GetDexFile()->GetRaw();
+ const RawDexFile::MethodId& method_id = raw->GetMethodId(src.method_idx_);
+ dst->klass_ = klass;
+ dst->name_.set(raw->dexStringById(method_id.name_idx_));
+ dst->proto_idx_ = method_id.proto_idx_;
+ dst->shorty_.set(raw->GetShorty(method_id.proto_idx_));
+ dst->access_flags_ = src.access_flags_;
+
+ // TODO: check for finalize method
+
+ const RawDexFile::CodeItem* code_item = raw->GetCodeItem(src);
+ if (code_item != NULL) {
+ dst->num_registers_ = code_item->registers_size_;
+ dst->num_ins_ = code_item->ins_size_;
+ dst->num_outs_ = code_item->outs_size_;
+ dst->insns_ = code_item->insns_;
+ } else {
+ uint16_t num_args = dst->NumArgRegisters();
+ if (!dst->IsStatic()) {
+ ++num_args;
+ }
+ dst->num_registers_ = dst->num_ins_ + num_args;
+ // TODO: native methods
+ }
+}
+
DexFile* ClassLinker::FindInClassPath(const char* descriptor) {
for (size_t i = 0; i != class_path_.size(); ++i) {
DexFile* dex_file = class_path_[i];
@@ -131,7 +283,7 @@ void ClassLinker::AppendToClassPath(DexFile* dex_file) {
}
Class* ClassLinker::CreatePrimitiveClass(JType type, const char* descriptor) {
- Class* klass = Heap::AllocClass();
+ Class* klass = Heap::AllocClass(NULL);
CHECK(klass != NULL);
klass->super_class_ = java_lang_Class_;
klass->access_flags_ = kAccPublic | kAccFinal | kAccAbstract;
@@ -348,8 +500,8 @@ bool ClassLinker::ValidateSuperClassDescriptors(const Class* klass) {
}
bool ClassLinker::HasSameMethodDescriptorClasses(const Method* method,
- const Class* klass1,
- const Class* klass2) {
+ const Class* klass1,
+ const Class* klass2) {
const RawDexFile* raw = method->GetClass()->GetDexFile()->GetRaw();
const RawDexFile::ProtoId& proto_id = raw->GetProtoId(method->proto_idx_);
RawDexFile::ParameterIterator *it;
@@ -378,8 +530,8 @@ bool ClassLinker::HasSameMethodDescriptorClasses(const Method* method,
// Returns true if classes referenced by the descriptor are the
// same classes in klass1 as they are in klass2.
bool ClassLinker::HasSameDescriptorClasses(const char* descriptor,
- const Class* klass1,
- const Class* klass2) {
+ const Class* klass1,
+ const Class* klass2) {
CHECK(descriptor != NULL);
CHECK(klass1 != NULL);
CHECK(klass2 != NULL);
@@ -432,7 +584,7 @@ void ClassLinker::InitializeStaticFields(Class* klass) {
return;
}
const char* descriptor = klass->GetDescriptor().data();
- RawDexFile* raw = dex_file->GetRaw();
+ const RawDexFile* raw = dex_file->GetRaw();
const RawDexFile::ClassDef* class_def = raw->FindClassDef(descriptor);
CHECK(class_def != NULL);
const byte* addr = raw->GetEncodedArray(*class_def);
diff --git a/src/class_linker.h b/src/class_linker.h
index 89fd8f7..3796dc2 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -30,6 +30,10 @@ class ClassLinker {
return FindClass(descriptor, NULL, NULL);
}
+ bool LoadClass(const char* descriptor, Class* klass);
+
+ bool LoadClass(const RawDexFile::ClassDef& class_def, Class* klass);
+
Class* FindPrimitiveClass(JType type);
bool InitializeClass(Class* klass);
@@ -47,6 +51,12 @@ class ClassLinker {
private:
Class* CreatePrimitiveClass(JType type, const char* descriptor);
+ void LoadInterfaces(const RawDexFile::ClassDef& class_def, Class *klass);
+
+ void LoadField(Class* klass, const RawDexFile::Field& src, Field* dst);
+
+ void LoadMethod(Class* klass, const RawDexFile::Method& src, Method* dst);
+
// Inserts a class into the class table. Returns true if the class
// was inserted.
bool InsertClass(Class* klass);
@@ -104,6 +114,7 @@ class ClassLinker {
Class* primitive_long_;
Class* primitive_void_;
+ Class* java_lang_Object_;
Class* java_lang_Class_;
DISALLOW_COPY_AND_ASSIGN(ClassLinker);
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index 7bb9ecb..5cd8a6f 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -1,31 +1,95 @@
// Copyright 2011 Google Inc. All Rights Reserved.
+#include "src/common_test.h"
#include "src/class_linker.h"
#include "src/dex_file.h"
+#include "src/heap.h"
#include "gtest/gtest.h"
namespace art {
-static const char kMyClassDex[] =
-"ZGV4CjAzNQDyNgSqujckc8oAvOKGLvz3+wrLfW9ED5AIAgAAcAAAAHhWNBIAAAAAAAAAAIABAAAG"
-"AAAAcAAAAAMAAACIAAAAAQAAAJQAAAAAAAAAAAAAAAIAAACgAAAAAgAAALAAAAAYAQAA8AAAABwB"
-"AAAkAQAALwEAAEMBAABRAQAAXgEAAAEAAAACAAAABQAAAAUAAAACAAAAAAAAAAAAAAAAAAAAAQAA"
-"AAAAAAABAAAAAQAAAP////8AAAAABAAAAAAAAABrAQAAAAAAAAAAAAAAAAAAAQAAAAAAAAADAAAA"
-"AAAAAHUBAAAAAAAAAQABAAAAAABhAQAAAQAAAA4AAAABAAEAAQAAAGYBAAAEAAAAcBABAAAADgAG"
-"PGluaXQ+AAlMTXlDbGFzczsAEkxqYXZhL2xhbmcvT2JqZWN0OwAMTXlDbGFzcy5qYXZhAAtPYmpl"
-"Y3QuamF2YQABVgADAAcOAAEABw4AAAABAAGBgATwAQAAAQAAgIAEhAIACwAAAAAAAAABAAAAAAAA"
-"AAEAAAAGAAAAcAAAAAIAAAADAAAAiAAAAAMAAAABAAAAlAAAAAUAAAACAAAAoAAAAAYAAAACAAAA"
-"sAAAAAEgAAACAAAA8AAAAAIgAAAGAAAAHAEAAAMgAAACAAAAYQEAAAAgAAACAAAAawEAAAAQAAAB"
-"AAAAgAEAAA==";
+TEST(ClassLinker, LoadNonexistent) {
+ scoped_ptr<DexFile> dex(DexFile::OpenBase64(kMyClassDex));
+ ASSERT_TRUE(dex != NULL);
+
+ ClassLinker linker;
+ linker.Init();
+ linker.AppendToClassPath(dex.get());
+
+ scoped_ptr<Class> klass(Heap::AllocClass(dex.get()));
+ bool result1 = linker.LoadClass("NoSuchClass", klass.get());
+ EXPECT_FALSE(result1);
+ bool result2 = linker.LoadClass("LNoSuchClass;", klass.get());
+ EXPECT_FALSE(result2);
+}
+
+TEST(ClassLinker, Load) {
+ scoped_ptr<DexFile> dex(DexFile::OpenBase64(kNestedDex));
+ ASSERT_TRUE(dex != NULL);
+
+ ClassLinker linker;
+ linker.Init();
+ linker.AppendToClassPath(dex.get());
+
+ scoped_ptr<Class> klass(Heap::AllocClass(dex.get()));
+ bool result = linker.LoadClass("LNested;", klass.get());
+ ASSERT_TRUE(result);
+
+ uint32_t vmeth = klass->NumVirtualMethods();
+ EXPECT_EQ(vmeth, 0U);
+
+ uint32_t dmeth = klass->NumDirectMethods();
+ EXPECT_EQ(dmeth, 1U);
+}
TEST(ClassLinker, FindClass) {
scoped_ptr<DexFile> dex(DexFile::OpenBase64(kMyClassDex));
ASSERT_TRUE(dex != NULL);
ClassLinker linker;
+ linker.Init();
linker.AppendToClassPath(dex.get());
- Class* klass = linker.FindClass("LMyClass;", NULL, dex.get());
- EXPECT_TRUE(klass != NULL);
+
+ Class* JavaLangObject = linker.FindClass("Ljava/lang/Object;", NULL, dex.get());
+ ASSERT_TRUE(JavaLangObject != NULL);
+ EXPECT_TRUE(JavaLangObject->GetClass() != NULL);
+ ASSERT_TRUE(JavaLangObject->GetDescriptor() == "Ljava/lang/Object;");
+ EXPECT_TRUE(JavaLangObject->GetSuperClass() == NULL);
+ EXPECT_FALSE(JavaLangObject->HasSuperClass());
+ EXPECT_TRUE(JavaLangObject->GetComponentType() == NULL);
+ EXPECT_FALSE(JavaLangObject->IsErroneous());
+ EXPECT_FALSE(JavaLangObject->IsVerified());
+ EXPECT_TRUE(JavaLangObject->IsLinked());
+ EXPECT_FALSE(JavaLangObject->IsArray());
+ EXPECT_FALSE(JavaLangObject->IsInterface());
+ EXPECT_TRUE(JavaLangObject->IsPublic());
+ EXPECT_FALSE(JavaLangObject->IsFinal());
+ EXPECT_FALSE(JavaLangObject->IsPrimitive());
+ EXPECT_EQ((size_t) 1, JavaLangObject->NumDirectMethods());
+ EXPECT_EQ((size_t) 0, JavaLangObject->NumVirtualMethods());
+ EXPECT_EQ((size_t) 0, JavaLangObject->NumInstanceFields());
+ EXPECT_EQ((size_t) 0, JavaLangObject->NumStaticFields());
+
+ Class* MyClass = linker.FindClass("LMyClass;", NULL, dex.get());
+ ASSERT_TRUE(MyClass != NULL);
+ EXPECT_TRUE(MyClass->GetClass() != NULL);
+ ASSERT_TRUE(MyClass->GetDescriptor() == "LMyClass;");
+ EXPECT_TRUE(MyClass->GetSuperClass() == JavaLangObject);
+ EXPECT_TRUE(MyClass->HasSuperClass());
+ EXPECT_TRUE(MyClass->GetComponentType() == NULL);
+ EXPECT_TRUE(MyClass->GetStatus() == Class::kStatusResolved);
+ EXPECT_FALSE(MyClass->IsErroneous());
+ EXPECT_FALSE(MyClass->IsVerified());
+ EXPECT_TRUE(MyClass->IsLinked());
+ EXPECT_FALSE(MyClass->IsArray());
+ EXPECT_FALSE(MyClass->IsInterface());
+ EXPECT_FALSE(MyClass->IsPublic());
+ EXPECT_FALSE(MyClass->IsFinal());
+ EXPECT_FALSE(MyClass->IsPrimitive());
+ EXPECT_EQ((size_t) 1, MyClass->NumDirectMethods());
+ EXPECT_EQ((size_t) 0, MyClass->NumVirtualMethods());
+ EXPECT_EQ((size_t) 0, MyClass->NumInstanceFields());
+ EXPECT_EQ((size_t) 0, MyClass->NumStaticFields());
}
} // namespace art
diff --git a/src/common_test.h b/src/common_test.h
new file mode 100644
index 0000000..9747261
--- /dev/null
+++ b/src/common_test.h
@@ -0,0 +1,89 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+namespace art {
+
+// package java.lang;
+// public class Object {}
+//
+// class MyClass {}
+static const char kMyClassDex[] =
+ "ZGV4CjAzNQA5Nm9IrCVm91COwepff7LhIE23GZIxGjgIAgAAcAAAAHhWNBIAAAAAAAAAAIABAAAG"
+ "AAAAcAAAAAMAAACIAAAAAQAAAJQAAAAAAAAAAAAAAAIAAACgAAAAAgAAALAAAAAYAQAA8AAAABwB"
+ "AAAkAQAALwEAAEMBAABRAQAAXgEAAAEAAAACAAAABQAAAAUAAAACAAAAAAAAAAAAAAAAAAAAAQAA"
+ "AAAAAAABAAAAAQAAAP////8AAAAABAAAAAAAAABrAQAAAAAAAAAAAAAAAAAAAQAAAAAAAAADAAAA"
+ "AAAAAHUBAAAAAAAAAQABAAAAAABhAQAAAQAAAA4AAAABAAEAAQAAAGYBAAAEAAAAcBABAAAADgAG"
+ "PGluaXQ+AAlMTXlDbGFzczsAEkxqYXZhL2xhbmcvT2JqZWN0OwAMTXlDbGFzcy5qYXZhAAtPYmpl"
+ "Y3QuamF2YQABVgACAAcOAAUABw4AAAABAAGBgATwAQAAAQAAgIAEhAIACwAAAAAAAAABAAAAAAAA"
+ "AAEAAAAGAAAAcAAAAAIAAAADAAAAiAAAAAMAAAABAAAAlAAAAAUAAAACAAAAoAAAAAYAAAACAAAA"
+ "sAAAAAEgAAACAAAA8AAAAAIgAAAGAAAAHAEAAAMgAAACAAAAYQEAAAAgAAACAAAAawEAAAAQAAAB"
+ "AAAAgAEAAA==";
+
+// class Nested {
+// class Inner {
+// }
+// }
+static const char kNestedDex[] =
+ "ZGV4CjAzNQAQedgAe7gM1B/WHsWJ6L7lGAISGC7yjD2IAwAAcAAAAHhWNBIAAAAAAAAAAMQCAAAP"
+ "AAAAcAAAAAcAAACsAAAAAgAAAMgAAAABAAAA4AAAAAMAAADoAAAAAgAAAAABAABIAgAAQAEAAK4B"
+ "AAC2AQAAvQEAAM0BAADXAQAA+wEAABsCAAA+AgAAUgIAAF8CAABiAgAAZgIAAHMCAAB5AgAAgQIA"
+ "AAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAkAAAAJAAAABgAAAAAAAAAKAAAABgAAAKgBAAAAAAEA"
+ "DQAAAAAAAQAAAAAAAQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAIAAAAiAEAAKsCAAAA"
+ "AAAAAQAAAAAAAAAFAAAAAAAAAAgAAACYAQAAuAIAAAAAAAACAAAAlAIAAJoCAAABAAAAowIAAAIA"
+ "AgABAAAAiAIAAAYAAABbAQAAcBACAAAADgABAAEAAQAAAI4CAAAEAAAAcBACAAAADgBAAQAAAAAA"
+ "AAAAAAAAAAAATAEAAAAAAAAAAAAAAAAAAAEAAAABAAY8aW5pdD4ABUlubmVyAA5MTmVzdGVkJElu"
+ "bmVyOwAITE5lc3RlZDsAIkxkYWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2"
+ "aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAhTGRhbHZpay9hbm5vdGF0aW9uL01lbWJlckNsYXNz"
+ "ZXM7ABJMamF2YS9sYW5nL09iamVjdDsAC05lc3RlZC5qYXZhAAFWAAJWTAALYWNjZXNzRmxhZ3MA"
+ "BG5hbWUABnRoaXMkMAAFdmFsdWUAAgEABw4AAQAHDjwAAgIBDhgBAgMCCwQADBcBAgQBDhwBGAAA"
+ "AQEAAJAgAICABNQCAAABAAGAgATwAgAAEAAAAAAAAAABAAAAAAAAAAEAAAAPAAAAcAAAAAIAAAAH"
+ "AAAArAAAAAMAAAACAAAAyAAAAAQAAAABAAAA4AAAAAUAAAADAAAA6AAAAAYAAAACAAAAAAEAAAMQ"
+ "AAACAAAAQAEAAAEgAAACAAAAVAEAAAYgAAACAAAAiAEAAAEQAAABAAAAqAEAAAIgAAAPAAAArgEA"
+ "AAMgAAACAAAAiAIAAAQgAAADAAAAlAIAAAAgAAACAAAAqwIAAAAQAAABAAAAxAIAAA==";
+
+// class ProtoCompare {
+// int m1(short x, int y, long z) { return x + y + (int)z; }
+// int m2(short x, int y, long z) { return x + y + (int)z; }
+// int m3(long x, int y, short z) { return (int)x + y + z; }
+// long m4(long x, int y, short z) { return x + y + z; }
+// }
+static const char kProtoCompareDex[] =
+ "ZGV4CjAzNQBLUetu+TVZ8gsYsCOFoij7ecsHaGSEGA8gAwAAcAAAAHhWNBIAAAAAAAAAAIwCAAAP"
+ "AAAAcAAAAAYAAACsAAAABAAAAMQAAAAAAAAAAAAAAAYAAAD0AAAAAQAAACQBAADcAQAARAEAAN4B"
+ "AADmAQAA6QEAAO8BAAD1AQAA+AEAAP4BAAAOAgAAIgIAADUCAAA4AgAAOwIAAD8CAABDAgAARwIA"
+ "AAEAAAAEAAAABgAAAAcAAAAJAAAACgAAAAIAAAAAAAAAyAEAAAMAAAAAAAAA1AEAAAUAAAABAAAA"
+ "yAEAAAoAAAAFAAAAAAAAAAIAAwAAAAAAAgABAAsAAAACAAEADAAAAAIAAAANAAAAAgACAA4AAAAD"
+ "AAMAAAAAAAIAAAAAAAAAAwAAAAAAAAAIAAAAAAAAAHACAAAAAAAAAQABAAEAAABLAgAABAAAAHAQ"
+ "BQAAAA4ABwAFAAAAAABQAgAABQAAAJAAAwSEUbAQDwAAAAcABQAAAAAAWAIAAAUAAACQAAMEhFGw"
+ "EA8AAAAGAAUAAAAAAGACAAAEAAAAhCCwQLBQDwAJAAUAAAAAAGgCAAAFAAAAgXC7UIGCuyAQAAAA"
+ "AwAAAAEAAAAEAAAAAwAAAAQAAAABAAY8aW5pdD4AAUkABElKSVMABElTSUoAAUoABEpKSVMADkxQ"
+ "cm90b0NvbXBhcmU7ABJMamF2YS9sYW5nL09iamVjdDsAEVByb3RvQ29tcGFyZS5qYXZhAAFTAAFW"
+ "AAJtMQACbTIAAm0zAAJtNAABAAcOAAIDAAAABw4AAwMAAAAHDgAEAwAAAAcOAAUDAAAABw4AAAAB"
+ "BACAgATEAgEA3AIBAPgCAQCUAwEArAMAAAwAAAAAAAAAAQAAAAAAAAABAAAADwAAAHAAAAACAAAA"
+ "BgAAAKwAAAADAAAABAAAAMQAAAAFAAAABgAAAPQAAAAGAAAAAQAAACQBAAABIAAABQAAAEQBAAAB"
+ "EAAAAgAAAMgBAAACIAAADwAAAN4BAAADIAAABQAAAEsCAAAAIAAAAQAAAHACAAAAEAAAAQAAAIwC"
+ "AAA=";
+
+// class ProtoCompare2 {
+// int m1(short x, int y, long z) { return x + y + (int)z; }
+// int m2(short x, int y, long z) { return x + y + (int)z; }
+// int m3(long x, int y, short z) { return (int)x + y + z; }
+// long m4(long x, int y, short z) { return x + y + z; }
+// }
+static const char kProtoCompare2Dex[] =
+ "ZGV4CjAzNQDVUXj687EpyTTDJZEZPA8dEYnDlm0Ir6YgAwAAcAAAAHhWNBIAAAAAAAAAAIwCAAAP"
+ "AAAAcAAAAAYAAACsAAAABAAAAMQAAAAAAAAAAAAAAAYAAAD0AAAAAQAAACQBAADcAQAARAEAAN4B"
+ "AADmAQAA6QEAAO8BAAD1AQAA+AEAAP4BAAAPAgAAIwIAADcCAAA6AgAAPQIAAEECAABFAgAASQIA"
+ "AAEAAAAEAAAABgAAAAcAAAAJAAAACgAAAAIAAAAAAAAAyAEAAAMAAAAAAAAA1AEAAAUAAAABAAAA"
+ "yAEAAAoAAAAFAAAAAAAAAAIAAwAAAAAAAgABAAsAAAACAAEADAAAAAIAAAANAAAAAgACAA4AAAAD"
+ "AAMAAAAAAAIAAAAAAAAAAwAAAAAAAAAIAAAAAAAAAHICAAAAAAAAAQABAAEAAABNAgAABAAAAHAQ"
+ "BQAAAA4ABwAFAAAAAABSAgAABQAAAJAAAwSEUbAQDwAAAAcABQAAAAAAWgIAAAUAAACQAAMEhFGw"
+ "EA8AAAAGAAUAAAAAAGICAAAEAAAAhCCwQLBQDwAJAAUAAAAAAGoCAAAFAAAAgXC7UIGCuyAQAAAA"
+ "AwAAAAEAAAAEAAAAAwAAAAQAAAABAAY8aW5pdD4AAUkABElKSVMABElTSUoAAUoABEpKSVMAD0xQ"
+ "cm90b0NvbXBhcmUyOwASTGphdmEvbGFuZy9PYmplY3Q7ABJQcm90b0NvbXBhcmUyLmphdmEAAVMA"
+ "AVYAAm0xAAJtMgACbTMAAm00AAEABw4AAgMAAAAHDgADAwAAAAcOAAQDAAAABw4ABQMAAAAHDgAA"
+ "AAEEAICABMQCAQDcAgEA+AIBAJQDAQCsAwwAAAAAAAAAAQAAAAAAAAABAAAADwAAAHAAAAACAAAA"
+ "BgAAAKwAAAADAAAABAAAAMQAAAAFAAAABgAAAPQAAAAGAAAAAQAAACQBAAABIAAABQAAAEQBAAAB"
+ "EAAAAgAAAMgBAAACIAAADwAAAN4BAAADIAAABQAAAE0CAAAAIAAAAQAAAHICAAAAEAAAAQAAAIwC"
+ "AAA=";
+
+} // namespace art
diff --git a/src/dex_file.cc b/src/dex_file.cc
index c9604a1..5b39bfc 100644
--- a/src/dex_file.cc
+++ b/src/dex_file.cc
@@ -49,147 +49,4 @@ void DexFile::Init() {
fields_ = new Field*[num_fields_]();
}
-bool DexFile::LoadClass(const char* descriptor, Class* klass) {
- const RawDexFile::ClassDef* class_def = raw_->FindClassDef(descriptor);
- if (class_def == NULL) {
- return false;
- } else {
- return LoadClass(*class_def, klass);
- }
-}
-
-bool DexFile::LoadClass(const RawDexFile::ClassDef& class_def, Class* klass) {
- CHECK(klass != NULL);
- const byte* class_data = raw_->GetClassData(class_def);
- RawDexFile::ClassDataHeader header = raw_->ReadClassDataHeader(&class_data);
-
- const char* descriptor = raw_->GetClassDescriptor(class_def);
- CHECK(descriptor != NULL);
-
- klass->klass_ = NULL; // TODO
- klass->descriptor_.set(descriptor);
- klass->descriptor_alloc_ = NULL;
- klass->access_flags_ = class_def.access_flags_;
- klass->class_loader_ = NULL; // TODO
- klass->dex_file_ = this;
- klass->primitive_type_ = Class::kPrimNot;
- klass->status_ = Class::kStatusIdx;
-
- klass->super_class_ = NULL;
- klass->super_class_idx_ = class_def.superclass_idx_;
-
- klass->num_sfields_ = header.static_fields_size_;
- klass->num_ifields_ = header.instance_fields_size_;
- klass->num_direct_methods_ = header.direct_methods_size_;
- klass->num_virtual_methods_ = header.virtual_methods_size_;
-
- klass->source_file_ = raw_->dexGetSourceFile(class_def);
-
- // Load class interfaces.
- LoadInterfaces(class_def, klass);
-
- // Load static fields.
- if (klass->num_sfields_ != 0) {
- // TODO: allocate on the object heap.
- klass->sfields_ = new StaticField[klass->NumStaticFields()]();
- uint32_t last_idx = 0;
- for (size_t i = 0; i < klass->num_sfields_; ++i) {
- RawDexFile::Field raw_field;
- raw_->dexReadClassDataField(&class_data, &raw_field, &last_idx);
- LoadField(klass, raw_field, &klass->sfields_[i]);
- }
- }
-
- // Load instance fields.
- if (klass->NumInstanceFields() != 0) {
- // TODO: allocate on the object heap.
- klass->ifields_ = new InstanceField[klass->NumInstanceFields()]();
- uint32_t last_idx = 0;
- for (size_t i = 0; i < klass->NumInstanceFields(); ++i) {
- RawDexFile::Field raw_field;
- raw_->dexReadClassDataField(&class_data, &raw_field, &last_idx);
- LoadField(klass, raw_field, klass->GetInstanceField(i));
- }
- }
-
- // Load direct methods.
- if (klass->NumDirectMethods() != 0) {
- // TODO: append direct methods to class object
- klass->direct_methods_ = new Method[klass->NumDirectMethods()]();
- uint32_t last_idx = 0;
- for (size_t i = 0; i < klass->NumDirectMethods(); ++i) {
- RawDexFile::Method raw_method;
- raw_->dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
- LoadMethod(klass, raw_method, klass->GetDirectMethod(i));
- // TODO: register maps
- }
- }
-
- // Load virtual methods.
- if (klass->NumVirtualMethods() != 0) {
- // TODO: append virtual methods to class object
- klass->virtual_methods_ = new Method[klass->NumVirtualMethods()]();
- uint32_t last_idx = 0;
- for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
- RawDexFile::Method raw_method;
- raw_->dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
- LoadMethod(klass, raw_method, klass->GetVirtualMethod(i));
- // TODO: register maps
- }
- }
-
- return klass;
-}
-
-void DexFile::LoadInterfaces(const RawDexFile::ClassDef& class_def,
- Class* klass) {
- const RawDexFile::TypeList* list = raw_->GetInterfacesList(class_def);
- if (list != NULL) {
- klass->interface_count_ = list->Size();
- // TODO: allocate the interfaces array on the object heap.
- klass->interfaces_ = new Class*[list->Size()]();
- for (size_t i = 0; i < list->Size(); ++i) {
- const RawDexFile::TypeItem& type_item = list->GetTypeItem(i);
- klass->interfaces_[i] = reinterpret_cast<Class*>(type_item.type_idx_);
- }
- }
-}
-
-void DexFile::LoadField(Class* klass, const RawDexFile::Field& src,
- Field* dst) {
- const RawDexFile::FieldId& field_id = raw_->GetFieldId(src.field_idx_);
- dst->klass_ = klass;
- dst->name_ = raw_->dexStringById(field_id.name_idx_);
- dst->signature_ = raw_->dexStringByTypeIdx(field_id.type_idx_);
- dst->access_flags_ = src.access_flags_;
-}
-
-void DexFile::LoadMethod(Class* klass, const RawDexFile::Method& src,
- Method* dst) {
- const RawDexFile::MethodId& method_id = raw_->GetMethodId(src.method_idx_);
- dst->klass_ = klass;
- dst->name_.set(raw_->dexStringById(method_id.name_idx_));
- dst->dex_file_ = this;
- dst->proto_idx_ = method_id.proto_idx_;
- dst->shorty_.set(raw_->GetShorty(method_id.proto_idx_));
- dst->access_flags_ = src.access_flags_;
-
- // TODO: check for finalize method
-
- const RawDexFile::CodeItem* code_item = raw_->GetCodeItem(src);
- if (code_item != NULL) {
- dst->num_registers_ = code_item->registers_size_;
- dst->num_ins_ = code_item->ins_size_;
- dst->num_outs_ = code_item->outs_size_;
- dst->insns_ = code_item->insns_;
- } else {
- uint16_t num_args = dst->NumArgRegisters();
- if (!dst->IsStatic()) {
- ++num_args;
- }
- dst->num_registers_ = dst->num_ins_ + num_args;
- // TODO: native methods
- }
-}
-
} // namespace art
diff --git a/src/dex_file.h b/src/dex_file.h
index 8463672..d11b3b5 100644
--- a/src/dex_file.h
+++ b/src/dex_file.h
@@ -40,10 +40,6 @@ class DexFile {
return num_methods_;
}
- bool LoadClass(const char* descriptor, Class* klass);
-
- bool LoadClass(const RawDexFile::ClassDef& class_def, Class* klass);
-
bool HasClass(const char* descriptor) {
return raw_->FindClassDef(descriptor) != NULL;
}
@@ -77,12 +73,6 @@ class DexFile {
void Init();
- void LoadInterfaces(const RawDexFile::ClassDef& class_def, Class *klass);
-
- void LoadField(Class* klass, const RawDexFile::Field& src, Field* dst);
-
- void LoadMethod(Class* klass, const RawDexFile::Method& src, Method* dst);
-
// Table of contents for interned String objects.
String** strings_;
size_t num_strings_;
diff --git a/src/dex_file_test.cc b/src/dex_file_test.cc
index ccac396..e12f8e2 100644
--- a/src/dex_file_test.cc
+++ b/src/dex_file_test.cc
@@ -1,5 +1,6 @@
// Copyright 2011 Google Inc. All Rights Reserved.
+#include "src/common_test.h"
#include "src/dex_file.h"
#include "src/object.h"
#include "src/scoped_ptr.h"
@@ -9,55 +10,9 @@
namespace art {
-// class Nested {
-// class Inner {
-// }
-// }
-static const char kNestedDex[] =
- "ZGV4CjAzNQAQedgAe7gM1B/WHsWJ6L7lGAISGC7yjD2IAwAAcAAAAHhWNBIAAAAAAAAAAMQCAAAP"
- "AAAAcAAAAAcAAACsAAAAAgAAAMgAAAABAAAA4AAAAAMAAADoAAAAAgAAAAABAABIAgAAQAEAAK4B"
- "AAC2AQAAvQEAAM0BAADXAQAA+wEAABsCAAA+AgAAUgIAAF8CAABiAgAAZgIAAHMCAAB5AgAAgQIA"
- "AAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAkAAAAJAAAABgAAAAAAAAAKAAAABgAAAKgBAAAAAAEA"
- "DQAAAAAAAQAAAAAAAQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAIAAAAiAEAAKsCAAAA"
- "AAAAAQAAAAAAAAAFAAAAAAAAAAgAAACYAQAAuAIAAAAAAAACAAAAlAIAAJoCAAABAAAAowIAAAIA"
- "AgABAAAAiAIAAAYAAABbAQAAcBACAAAADgABAAEAAQAAAI4CAAAEAAAAcBACAAAADgBAAQAAAAAA"
- "AAAAAAAAAAAATAEAAAAAAAAAAAAAAAAAAAEAAAABAAY8aW5pdD4ABUlubmVyAA5MTmVzdGVkJElu"
- "bmVyOwAITE5lc3RlZDsAIkxkYWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2"
- "aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAhTGRhbHZpay9hbm5vdGF0aW9uL01lbWJlckNsYXNz"
- "ZXM7ABJMamF2YS9sYW5nL09iamVjdDsAC05lc3RlZC5qYXZhAAFWAAJWTAALYWNjZXNzRmxhZ3MA"
- "BG5hbWUABnRoaXMkMAAFdmFsdWUAAgEABw4AAQAHDjwAAgIBDhgBAgMCCwQADBcBAgQBDhwBGAAA"
- "AQEAAJAgAICABNQCAAABAAGAgATwAgAAEAAAAAAAAAABAAAAAAAAAAEAAAAPAAAAcAAAAAIAAAAH"
- "AAAArAAAAAMAAAACAAAAyAAAAAQAAAABAAAA4AAAAAUAAAADAAAA6AAAAAYAAAACAAAAAAEAAAMQ"
- "AAACAAAAQAEAAAEgAAACAAAAVAEAAAYgAAACAAAAiAEAAAEQAAABAAAAqAEAAAIgAAAPAAAArgEA"
- "AAMgAAACAAAAiAIAAAQgAAADAAAAlAIAAAAgAAACAAAAqwIAAAAQAAABAAAAxAIAAA==";
-
TEST(DexFile, Open) {
scoped_ptr<DexFile> dex(DexFile::OpenBase64(kNestedDex));
ASSERT_TRUE(dex != NULL);
}
-TEST(DexFile, LoadNonexistent) {
- scoped_ptr<DexFile> dex(DexFile::OpenBase64(kNestedDex));
- ASSERT_TRUE(dex != NULL);
-
- scoped_ptr<Class> klass(reinterpret_cast<Class*>(new byte[sizeof(Class)]));
- bool result = dex->LoadClass("NoSuchClass", klass.get());
- ASSERT_FALSE(result);
-}
-
-TEST(DexFile, Load) {
- scoped_ptr<DexFile> dex(DexFile::OpenBase64(kNestedDex));
- ASSERT_TRUE(dex != NULL);
-
- scoped_ptr<Class> klass(reinterpret_cast<Class*>(new byte[sizeof(Class)]));
- bool result = dex->LoadClass("LNested;", klass.get());
- ASSERT_TRUE(result);
-
- uint32_t vmeth = klass->NumVirtualMethods();
- EXPECT_EQ(vmeth, 0U);
-
- uint32_t dmeth = klass->NumDirectMethods();
- EXPECT_EQ(dmeth, 1U);
-}
-
} // namespace art
diff --git a/src/heap.h b/src/heap.h
index d6b1649..7b31ebc 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -11,9 +11,11 @@ namespace art {
class Heap {
public:
- static Class* AllocClass() {
+ static Class* AllocClass(DexFile* dex_file) {
byte* raw = new byte[sizeof(Class)]();
- return reinterpret_cast<Class*>(raw);
+ Class* klass = reinterpret_cast<Class*>(raw);
+ klass->dex_file_ = dex_file;
+ return klass;
}
static CharArray* AllocCharArray(size_t length) {
diff --git a/src/object.cc b/src/object.cc
index 7c28d76..d897c52 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -69,9 +69,9 @@ uint32_t Method::NumArgRegisters() {
}
bool Method::HasSameArgumentTypes(const Method* that) const {
- const RawDexFile* raw1 = this->dex_file_->GetRaw();
+ const RawDexFile* raw1 = this->GetClass()->GetDexFile()->GetRaw();
const RawDexFile::ProtoId& proto1 = raw1->GetProtoId(this->proto_idx_);
- const RawDexFile* raw2 = that->dex_file_->GetRaw();
+ const RawDexFile* raw2 = that->GetClass()->GetDexFile()->GetRaw();
const RawDexFile::ProtoId& proto2 = raw2->GetProtoId(that->proto_idx_);
// TODO: compare ProtoId objects for equality and exit early
@@ -101,11 +101,11 @@ bool Method::HasSameArgumentTypes(const Method* that) const {
}
bool Method::HasSameReturnType(const Method* that) const {
- const RawDexFile* raw1 = this->dex_file_->GetRaw();
+ const RawDexFile* raw1 = this->GetClass()->GetDexFile()->GetRaw();
const RawDexFile::ProtoId& proto1 = raw1->GetProtoId(this->proto_idx_);
const char* type1 = raw1->dexStringByTypeIdx(proto1.return_type_idx_);
- const RawDexFile* raw2 = that->dex_file_->GetRaw();
+ const RawDexFile* raw2 = that->GetClass()->GetDexFile()->GetRaw();
const RawDexFile::ProtoId& proto2 = raw2->GetProtoId(that->proto_idx_);
const char* type2 = raw2->dexStringByTypeIdx(proto2.return_type_idx_);
diff --git a/src/object.h b/src/object.h
index 2b75ff7..3bad627 100644
--- a/src/object.h
+++ b/src/object.h
@@ -311,7 +311,7 @@ class Method {
}
// const char* GetReturnTypeDescriptor() const {
- // return dex_file_->GetRaw()->dexStringByTypeIdx(proto_id_.return_type_id_);
+ // return klass_->GetDexFile_->GetRaw()->dexStringByTypeIdx(proto_id_.return_type_id_);
// }
// Returns true if the method is declared public.
@@ -398,10 +398,6 @@ class Method {
// method name, e.g. "<init>" or "eatLunch"
StringPiece name_;
- // A pointer to the DEX file this class was loaded from or NULL for
- // proxy objects.
- DexFile* dex_file_;
-
// Method prototype descriptor string (return and argument types).
uint32_t proto_idx_;
diff --git a/src/object_test.cc b/src/object_test.cc
index 6ce3570..49dda32 100644
--- a/src/object_test.cc
+++ b/src/object_test.cc
@@ -1,7 +1,10 @@
// Copyright 2011 Google Inc. All Rights Reserved.
// Author: cshapiro@google.com (Carl Shapiro)
+#include "src/class_linker.h"
+#include "src/common_test.h"
#include "src/dex_file.h"
+#include "src/heap.h"
#include "src/object.h"
#include "src/scoped_ptr.h"
@@ -24,37 +27,18 @@ TEST(Object, IsInSamePackage) {
"Ljava/lang/reflect/Method;"));
}
-// class ProtoCompare {
-// int m1(short x, int y, long z) { return x + y + (int)z; }
-// int m2(short x, int y, long z) { return x + y + (int)z; }
-// int m3(long x, int y, short z) { return (int)x + y + z; }
-// long m4(long x, int y, short z) { return x + y + z; }
-// }
-static const char kProtoCompareDex[] =
- "ZGV4CjAzNQBLUetu+TVZ8gsYsCOFoij7ecsHaGSEGA8gAwAAcAAAAHhWNBIAAAAAAAAAAIwCAAAP"
- "AAAAcAAAAAYAAACsAAAABAAAAMQAAAAAAAAAAAAAAAYAAAD0AAAAAQAAACQBAADcAQAARAEAAN4B"
- "AADmAQAA6QEAAO8BAAD1AQAA+AEAAP4BAAAOAgAAIgIAADUCAAA4AgAAOwIAAD8CAABDAgAARwIA"
- "AAEAAAAEAAAABgAAAAcAAAAJAAAACgAAAAIAAAAAAAAAyAEAAAMAAAAAAAAA1AEAAAUAAAABAAAA"
- "yAEAAAoAAAAFAAAAAAAAAAIAAwAAAAAAAgABAAsAAAACAAEADAAAAAIAAAANAAAAAgACAA4AAAAD"
- "AAMAAAAAAAIAAAAAAAAAAwAAAAAAAAAIAAAAAAAAAHACAAAAAAAAAQABAAEAAABLAgAABAAAAHAQ"
- "BQAAAA4ABwAFAAAAAABQAgAABQAAAJAAAwSEUbAQDwAAAAcABQAAAAAAWAIAAAUAAACQAAMEhFGw"
- "EA8AAAAGAAUAAAAAAGACAAAEAAAAhCCwQLBQDwAJAAUAAAAAAGgCAAAFAAAAgXC7UIGCuyAQAAAA"
- "AwAAAAEAAAAEAAAAAwAAAAQAAAABAAY8aW5pdD4AAUkABElKSVMABElTSUoAAUoABEpKSVMADkxQ"
- "cm90b0NvbXBhcmU7ABJMamF2YS9sYW5nL09iamVjdDsAEVByb3RvQ29tcGFyZS5qYXZhAAFTAAFW"
- "AAJtMQACbTIAAm0zAAJtNAABAAcOAAIDAAAABw4AAwMAAAAHDgAEAwAAAAcOAAUDAAAABw4AAAAB"
- "BACAgATEAgEA3AIBAPgCAQCUAwEArAMAAAwAAAAAAAAAAQAAAAAAAAABAAAADwAAAHAAAAACAAAA"
- "BgAAAKwAAAADAAAABAAAAMQAAAAFAAAABgAAAPQAAAAGAAAAAQAAACQBAAABIAAABQAAAEQBAAAB"
- "EAAAAgAAAMgBAAACIAAADwAAAN4BAAADIAAABQAAAEsCAAAAIAAAAQAAAHACAAAAEAAAAQAAAIwC"
- "AAA=";
-
// TODO: test 0 argument methods
// TODO: make this test simpler and shorter
TEST(Method, ProtoCompare) {
scoped_ptr<DexFile> dex_file(DexFile::OpenBase64(kProtoCompareDex));
ASSERT_TRUE(dex_file != NULL);
- scoped_ptr<Class> klass(reinterpret_cast<Class*>(new byte[sizeof(Class)]));
- bool result = dex_file->LoadClass("LProtoCompare;", klass.get());
+ ClassLinker linker;
+ linker.Init();
+ linker.AppendToClassPath(dex_file.get());
+
+ scoped_ptr<Class> klass(Heap::AllocClass(dex_file.get()));
+ bool result = linker.LoadClass("LProtoCompare;", klass.get());
ASSERT_TRUE(result);
ASSERT_EQ(4U, klass->NumVirtualMethods());
@@ -102,40 +86,23 @@ TEST(Method, ProtoCompare) {
EXPECT_FALSE(m1->HasSameNameAndPrototype(m2));
}
-// class ProtoCompare2 {
-// int m1(short x, int y, long z) { return x + y + (int)z; }
-// int m2(short x, int y, long z) { return x + y + (int)z; }
-// int m3(long x, int y, short z) { return (int)x + y + z; }
-// long m4(long x, int y, short z) { return x + y + z; }
-// }
-static const char kProtoCompare2Dex[] =
- "ZGV4CjAzNQDVUXj687EpyTTDJZEZPA8dEYnDlm0Ir6YgAwAAcAAAAHhWNBIAAAAAAAAAAIwCAAAP"
- "AAAAcAAAAAYAAACsAAAABAAAAMQAAAAAAAAAAAAAAAYAAAD0AAAAAQAAACQBAADcAQAARAEAAN4B"
- "AADmAQAA6QEAAO8BAAD1AQAA+AEAAP4BAAAPAgAAIwIAADcCAAA6AgAAPQIAAEECAABFAgAASQIA"
- "AAEAAAAEAAAABgAAAAcAAAAJAAAACgAAAAIAAAAAAAAAyAEAAAMAAAAAAAAA1AEAAAUAAAABAAAA"
- "yAEAAAoAAAAFAAAAAAAAAAIAAwAAAAAAAgABAAsAAAACAAEADAAAAAIAAAANAAAAAgACAA4AAAAD"
- "AAMAAAAAAAIAAAAAAAAAAwAAAAAAAAAIAAAAAAAAAHICAAAAAAAAAQABAAEAAABNAgAABAAAAHAQ"
- "BQAAAA4ABwAFAAAAAABSAgAABQAAAJAAAwSEUbAQDwAAAAcABQAAAAAAWgIAAAUAAACQAAMEhFGw"
- "EA8AAAAGAAUAAAAAAGICAAAEAAAAhCCwQLBQDwAJAAUAAAAAAGoCAAAFAAAAgXC7UIGCuyAQAAAA"
- "AwAAAAEAAAAEAAAAAwAAAAQAAAABAAY8aW5pdD4AAUkABElKSVMABElTSUoAAUoABEpKSVMAD0xQ"
- "cm90b0NvbXBhcmUyOwASTGphdmEvbGFuZy9PYmplY3Q7ABJQcm90b0NvbXBhcmUyLmphdmEAAVMA"
- "AVYAAm0xAAJtMgACbTMAAm00AAEABw4AAgMAAAAHDgADAwAAAAcOAAQDAAAABw4ABQMAAAAHDgAA"
- "AAEEAICABMQCAQDcAgEA+AIBAJQDAQCsAwwAAAAAAAAAAQAAAAAAAAABAAAADwAAAHAAAAACAAAA"
- "BgAAAKwAAAADAAAABAAAAMQAAAAFAAAABgAAAPQAAAAGAAAAAQAAACQBAAABIAAABQAAAEQBAAAB"
- "EAAAAgAAAMgBAAACIAAADwAAAN4BAAADIAAABQAAAE0CAAAAIAAAAQAAAHICAAAAEAAAAQAAAIwC"
- "AAA=";
-
TEST(Method, ProtoCompare2) {
scoped_ptr<DexFile> dex_file1(DexFile::OpenBase64(kProtoCompareDex));
ASSERT_TRUE(dex_file1 != NULL);
scoped_ptr<DexFile> dex_file2(DexFile::OpenBase64(kProtoCompare2Dex));
ASSERT_TRUE(dex_file2 != NULL);
-
- scoped_ptr<Class> klass1(reinterpret_cast<Class*>(new byte[sizeof(Class)]));
- bool result1 = dex_file1->LoadClass("LProtoCompare;", klass1.get());
+ ClassLinker linker1;
+ linker1.Init();
+ linker1.AppendToClassPath(dex_file1.get());
+ ClassLinker linker2;
+ linker2.Init();
+ linker2.AppendToClassPath(dex_file2.get());
+
+ scoped_ptr<Class> klass1(Heap::AllocClass(dex_file1.get()));
+ bool result1 = linker1.LoadClass("LProtoCompare;", klass1.get());
ASSERT_TRUE(result1);
- scoped_ptr<Class> klass2(reinterpret_cast<Class*>(new byte[sizeof(Class)]));
- bool result2 = dex_file2->LoadClass("LProtoCompare2;", klass2.get());
+ scoped_ptr<Class> klass2(Heap::AllocClass(dex_file2.get()));
+ bool result2 = linker2.LoadClass("LProtoCompare2;", klass2.get());
ASSERT_TRUE(result2);
Method* m1_1 = klass1->GetVirtualMethod(0);
diff --git a/src/raw_dex_file.cc b/src/raw_dex_file.cc
index 145509a..2d97a9a 100644
--- a/src/raw_dex_file.cc
+++ b/src/raw_dex_file.cc
@@ -155,9 +155,9 @@ void RawDexFile::InitIndex() {
}
}
-const RawDexFile::ClassDef* RawDexFile::FindClassDef(const char* descriptor) {
+const RawDexFile::ClassDef* RawDexFile::FindClassDef(const char* descriptor) const {
CHECK(descriptor != NULL);
- Index::iterator it = index_.find(descriptor);
+ Index::const_iterator it = index_.find(descriptor);
if (it == index_.end()) {
return NULL;
} else {
@@ -223,7 +223,7 @@ static uint64_t ReadUnsignedLong(const byte* ptr, int zwidth,
}
RawDexFile::ValueType RawDexFile::ReadEncodedValue(const byte** stream,
- JValue* value) {
+ JValue* value) const {
const byte* ptr = *stream;
byte value_type = *ptr++;
byte value_arg = value_type >> kEncodedValueArgShift;
diff --git a/src/raw_dex_file.h b/src/raw_dex_file.h
index db3d8a2..6f8a581 100644
--- a/src/raw_dex_file.h
+++ b/src/raw_dex_file.h
@@ -227,7 +227,7 @@ class RawDexFile {
}
// Looks up a class definition by its class descriptor.
- const ClassDef* FindClassDef(const char* descriptor);
+ const ClassDef* FindClassDef(const char* descriptor) const;
// Returns the number of string identifiers in the .dex file.
size_t NumStringIds() const {
@@ -276,7 +276,7 @@ class RawDexFile {
}
// Decodes the header section from the raw class data bytes.
- ClassDataHeader ReadClassDataHeader(const byte** class_data) {
+ ClassDataHeader ReadClassDataHeader(const byte** class_data) const {
CHECK(class_data != NULL);
ClassDataHeader header;
memset(&header, 0, sizeof(ClassDataHeader));
@@ -349,7 +349,7 @@ class RawDexFile {
}
// Returns the short form method descriptor for the given prototype.
- const char* GetShorty(uint32_t proto_idx) {
+ const char* GetShorty(uint32_t proto_idx) const {
const ProtoId& proto_id = GetProtoId(proto_idx);
return dexStringById(proto_id.shorty_idx_);
}
@@ -376,7 +376,7 @@ class RawDexFile {
return DecodeUnsignedLeb128(&ptr);
}
- ValueType ReadEncodedValue(const byte** encoded_value, JValue* value);
+ ValueType ReadEncodedValue(const byte** encoded_value, JValue* value) const;
// From libdex...
diff --git a/src/raw_dex_file_test.cc b/src/raw_dex_file_test.cc
index 1dd1485..8b0c130 100644
--- a/src/raw_dex_file_test.cc
+++ b/src/raw_dex_file_test.cc
@@ -1,5 +1,6 @@
// Copyright 2011 Google Inc. All Rights Reserved.
+#include "src/common_test.h"
#include "src/dex_file.h"
#include "src/raw_dex_file.h"
#include "src/scoped_ptr.h"
@@ -9,29 +10,6 @@
namespace art {
-// class Nested {
-// class Inner {
-// }
-// }
-static const char kNestedDex[] =
- "ZGV4CjAzNQAQedgAe7gM1B/WHsWJ6L7lGAISGC7yjD2IAwAAcAAAAHhWNBIAAAAAAAAAAMQCAAAP"
- "AAAAcAAAAAcAAACsAAAAAgAAAMgAAAABAAAA4AAAAAMAAADoAAAAAgAAAAABAABIAgAAQAEAAK4B"
- "AAC2AQAAvQEAAM0BAADXAQAA+wEAABsCAAA+AgAAUgIAAF8CAABiAgAAZgIAAHMCAAB5AgAAgQIA"
- "AAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAkAAAAJAAAABgAAAAAAAAAKAAAABgAAAKgBAAAAAAEA"
- "DQAAAAAAAQAAAAAAAQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAIAAAAiAEAAKsCAAAA"
- "AAAAAQAAAAAAAAAFAAAAAAAAAAgAAACYAQAAuAIAAAAAAAACAAAAlAIAAJoCAAABAAAAowIAAAIA"
- "AgABAAAAiAIAAAYAAABbAQAAcBACAAAADgABAAEAAQAAAI4CAAAEAAAAcBACAAAADgBAAQAAAAAA"
- "AAAAAAAAAAAATAEAAAAAAAAAAAAAAAAAAAEAAAABAAY8aW5pdD4ABUlubmVyAA5MTmVzdGVkJElu"
- "bmVyOwAITE5lc3RlZDsAIkxkYWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2"
- "aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAhTGRhbHZpay9hbm5vdGF0aW9uL01lbWJlckNsYXNz"
- "ZXM7ABJMamF2YS9sYW5nL09iamVjdDsAC05lc3RlZC5qYXZhAAFWAAJWTAALYWNjZXNzRmxhZ3MA"
- "BG5hbWUABnRoaXMkMAAFdmFsdWUAAgEABw4AAQAHDjwAAgIBDhgBAgMCCwQADBcBAgQBDhwBGAAA"
- "AQEAAJAgAICABNQCAAABAAGAgATwAgAAEAAAAAAAAAABAAAAAAAAAAEAAAAPAAAAcAAAAAIAAAAH"
- "AAAArAAAAAMAAAACAAAAyAAAAAQAAAABAAAA4AAAAAUAAAADAAAA6AAAAAYAAAACAAAAAAEAAAMQ"
- "AAACAAAAQAEAAAEgAAACAAAAVAEAAAYgAAACAAAAiAEAAAEQAAABAAAAqAEAAAIgAAAPAAAArgEA"
- "AAMgAAACAAAAiAIAAAQgAAADAAAAlAIAAAAgAAACAAAAqwIAAAAQAAABAAAAxAIAAA==";
-
-
TEST(RawDexFile, Open) {
scoped_ptr<RawDexFile> raw(RawDexFile::OpenBase64(kNestedDex));
ASSERT_TRUE(raw != NULL);