Make ClassLinker set Class::super_class_ plus test and build improvements
Create placeholder ClassLinker::java_lang_Object_ for use a
super-class of java_lang_Class_ instances.
src/class_linker.cc
src/class_linker.h
Expand ClassLinker FindClass test to verify Class::GetSuperClass
src/class_linker_test.cc
Move DexFile::Load* methods to ClassLinker so they can reference
java_lang_Object_ and java_lang_Class_
src/class_linker.cc
src/class_linker.h
src/dex_file.cc
src/dex_file.h
Move corresponding Load tests from class_linker_test to dex_file_test
src/class_linker_test.cc
src/dex_file_test.cc
Tracking change to object_test to use ClassLinker::Load* methods
src/object_test.cc
Move base64 to new src/common_test.h for reuse accross tests. Add
missing example source for MyClass dex.
src/common_test.h
src/class_linker_test.cc
src/dex_file_test.cc
src/object_test.cc
Change Heap::AllocClass to take DexFile argument
src/heap.h
Remove Method::dex_file_ in favor of using Method::GetClass::GetDexFile
src/object.cc
src/object.h
Made a few more RawDexFile methods const
src/raw_dex_file.cc
src/raw_dex_file.h
Add convenience targets for build-art and test-art-host
Android.mk
Drop use of _LOCAL_ from make variants, which isn't the appropriate
here, where we aren't differentiating between LOCAL_ and PRIVATE_.
Avoid redefinition of variables based on now removed
LIBART_TARGET_ARCH and TEST_TARGET_ARCH to support phony targets in
Android.mk
build/Android.aexec.host.mk
build/Android.aexec.mk
build/Android.common.mk
build/Android.libart.host.mk
build/Android.libart.mk
build/Android.test.host.mk
build/Android.test.mk
Change-Id: I84ce2b7a2b4e37799d4d782b97c02d5e97ac081c
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