Change Class::component_type_ and implement reflect.Array
Change-Id: I9e06f31577551c738eca2621146c8d2328119442
diff --git a/src/class_linker.cc b/src/class_linker.cc
index e3b4eea..0f02d09 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -129,12 +129,14 @@
// Object[] next to hold class roots
Class* object_array_class = AllocClass(java_lang_Class, sizeof(Class));
- object_array_class->SetArrayRank(1);
object_array_class->SetComponentType(java_lang_Object);
+ // Setup the char class to be used for char[]
+ Class* char_class = AllocClass(java_lang_Class, sizeof(Class));
+
// Setup the char[] class to be used for String
Class* char_array_class = AllocClass(java_lang_Class, sizeof(Class));
- char_array_class->SetArrayRank(1);
+ char_array_class->SetComponentType(char_class);
CharArray::SetArrayClass(char_array_class);
// Setup String
@@ -162,7 +164,6 @@
// Setup the primitive type classes.
SetClassRoot(kPrimitiveBoolean, CreatePrimitiveClass("Z", Class::kPrimBoolean));
SetClassRoot(kPrimitiveByte, CreatePrimitiveClass("B", Class::kPrimByte));
- SetClassRoot(kPrimitiveChar, CreatePrimitiveClass("C", Class::kPrimChar));
SetClassRoot(kPrimitiveShort, CreatePrimitiveClass("S", Class::kPrimShort));
SetClassRoot(kPrimitiveInt, CreatePrimitiveClass("I", Class::kPrimInt));
SetClassRoot(kPrimitiveLong, CreatePrimitiveClass("J", Class::kPrimLong));
@@ -170,16 +171,12 @@
SetClassRoot(kPrimitiveDouble, CreatePrimitiveClass("D", Class::kPrimDouble));
SetClassRoot(kPrimitiveVoid, CreatePrimitiveClass("V", Class::kPrimVoid));
- // Backfill component type of char[]
- char_array_class->SetComponentType(GetClassRoot(kPrimitiveChar));
-
// Create array interface entries to populate once we can load system classes
array_interfaces_ = AllocObjectArray<Class>(2);
array_iftable_ = AllocObjectArray<InterfaceEntry>(2);
// Create int array type for AllocDexCache (done in AppendToBootClassPath)
Class* int_array_class = AllocClass(java_lang_Class, sizeof(Class));
- int_array_class->SetArrayRank(1);
int_array_class->SetDescriptor(intern_table_->InternStrong("[I"));
int_array_class->SetComponentType(GetClassRoot(kPrimitiveInt));
IntArray::SetArrayClass(int_array_class);
@@ -220,6 +217,10 @@
// now we can use FindSystemClass
+ // run char class through InitializePrimitiveClass to finish init
+ InitializePrimitiveClass(char_class, "C", Class::kPrimChar);
+ SetClassRoot(kPrimitiveChar, char_class); // needs descriptor
+
// Object and String need to be rerun through FindSystemClass to finish init
java_lang_Object->SetStatus(Class::kStatusNotReady);
Class* Object_class = FindSystemClass("Ljava/lang/Object;");
@@ -614,7 +615,7 @@
Class* klass = LookupClass(descriptor, class_loader);
if (klass == NULL) {
// Class is not yet loaded.
- if (descriptor[0] == '[') {
+ if (descriptor[0] == '[' && descriptor[1] != '\0') {
return CreateArrayClass(descriptor, class_loader);
}
const DexFile::ClassPath& class_path = ((class_loader != NULL)
@@ -979,18 +980,18 @@
return NULL;
}
-Class* ClassLinker::CreatePrimitiveClass(const char* descriptor,
- Class::PrimitiveType type) {
+Class* ClassLinker::InitializePrimitiveClass(Class* primitive_class,
+ const char* descriptor,
+ Class::PrimitiveType type) {
// TODO: deduce one argument from the other
- Class* klass = AllocClass(sizeof(Class));
- CHECK(klass != NULL);
- klass->SetAccessFlags(kAccPublic | kAccFinal | kAccAbstract);
- klass->SetDescriptor(intern_table_->InternStrong(descriptor));
- klass->SetPrimitiveType(type);
- klass->SetStatus(Class::kStatusInitialized);
- bool success = InsertClass(descriptor, klass);
- CHECK(success) << "CreatePrimitiveClass(" << descriptor << ") failed";
- return klass;
+ CHECK(primitive_class != NULL);
+ primitive_class->SetAccessFlags(kAccPublic | kAccFinal | kAccAbstract);
+ primitive_class->SetDescriptor(intern_table_->InternStrong(descriptor));
+ primitive_class->SetPrimitiveType(type);
+ primitive_class->SetStatus(Class::kStatusInitialized);
+ bool success = InsertClass(descriptor, primitive_class);
+ CHECK(success) << "InitPrimitiveClass(" << descriptor << ") failed";
+ return primitive_class;
}
// Create an array class (i.e. the class object for the array, not the
@@ -1000,44 +1001,20 @@
// If "descriptor" refers to an array of primitives, look up the
// primitive type's internally-generated class object.
//
-// "loader" is the class loader of the class that's referring to us. It's
-// used to ensure that we're looking for the element type in the right
-// context. It does NOT become the class loader for the array class; that
-// always comes from the base element class.
+// "class_loader" is the class loader of the class that's referring to
+// us. It's used to ensure that we're looking for the element type in
+// the right context. It does NOT become the class loader for the
+// array class; that always comes from the base element class.
//
// Returns NULL with an exception raised on failure.
Class* ClassLinker::CreateArrayClass(const StringPiece& descriptor,
const ClassLoader* class_loader) {
CHECK_EQ('[', descriptor[0]);
- // Identify the underlying element class and the array dimension depth.
- Class* component_type = NULL;
- int array_rank;
- if (descriptor[1] == '[') {
- // array of arrays; keep descriptor and grab stuff from parent
- Class* outer = FindClass(descriptor.substr(1), class_loader);
- if (outer != NULL) {
- // want the base class, not "outer", in our component_type
- component_type = outer->GetComponentType();
- array_rank = outer->GetArrayRank() + 1;
- } else {
- DCHECK(component_type == NULL); // make sure we fail
- }
- } else {
- array_rank = 1;
- if (descriptor[1] == 'L') {
- // array of objects; strip off "[" and look up descriptor.
- const StringPiece subDescriptor = descriptor.substr(1);
- component_type = FindClass(subDescriptor, class_loader);
- } else {
- // array of a primitive type
- component_type = FindPrimitiveClass(descriptor[1]);
- }
- }
-
+ // Identify the underlying component type
+ Class* component_type = FindClass(descriptor.substr(1), class_loader);
if (component_type == NULL) {
- // failed
- // DCHECK(Thread::Current()->IsExceptionPending()); // TODO
+ DCHECK(Thread::Current()->IsExceptionPending());
return NULL;
}
@@ -1090,10 +1067,8 @@
if (new_class == NULL) {
return NULL;
}
- new_class->SetArrayRank(array_rank);
new_class->SetComponentType(component_type);
}
- DCHECK_LE(1, new_class->GetArrayRank());
DCHECK(new_class->GetComponentType() != NULL);
if (new_class->GetDescriptor() != NULL) {
DCHECK(new_class->GetDescriptor()->Equals(descriptor));