Store static field values in arrays.

Each static field is stored in one of three arrays:
 - references are stored in static_references_
 - 64 bit primitives are stored in static_64bit_primitives_
 - everything else is in static_32bit_primitives_

Change-Id: I1c0e182582f776c62edbd9bd97ffd4fd7e516c99
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index a8e1df1..03b6dfb 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -133,6 +133,7 @@
     for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
       Method* method = klass->GetDirectMethod(i);
       EXPECT_TRUE(method != NULL);
+      EXPECT_EQ(klass, method->GetDeclaringClass());
     }
 
     for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
@@ -144,12 +145,14 @@
       InstanceField* field = klass->GetInstanceField(i);
       EXPECT_TRUE(field != NULL);
       EXPECT_FALSE(field->IsStatic());
+      EXPECT_EQ(klass, field->GetDeclaringClass());
     }
 
     for (size_t i = 0; i < klass->NumStaticFields(); i++) {
       StaticField* field = klass->GetStaticField(i);
       EXPECT_TRUE(field != NULL);
       EXPECT_TRUE(field->IsStatic());
+      EXPECT_EQ(klass, field->GetDeclaringClass());
     }
 
     // Confirm that all instances fields are packed together at the start
@@ -388,4 +391,75 @@
   EXPECT_NE(MyClass_1, MyClass_2);
 }
 
+TEST_F(ClassLinkerTest, StaticFields) {
+  // TODO: uncomment expectations of initial values when InitializeClass works
+  scoped_ptr<DexFile> dex(OpenDexFileBase64(kStatics));
+  PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
+  Class* statics = class_linker_->FindClass("LStatics;", class_loader);
+  // class_linker_->InitializeClass(statics);  // TODO uncomment this
+
+  EXPECT_EQ(10U, statics->NumStaticFields());
+
+  StaticField* s0 = statics->GetStaticField(0);
+  EXPECT_EQ("Ljava/lang/reflect/Field;", s0->GetClass()->descriptor_);
+  EXPECT_EQ('Z', s0->GetType());
+//  EXPECT_EQ(true, s0->GetBoolean());  // TODO uncomment this
+  s0->SetBoolean(false);
+
+  StaticField* s1 = statics->GetStaticField(1);
+  EXPECT_EQ('B', s1->GetType());
+//  EXPECT_EQ(5, s1->GetByte());  // TODO uncomment this
+  s1->SetByte(6);
+
+  StaticField* s2 = statics->GetStaticField(2);
+  EXPECT_EQ('C', s2->GetType());
+//  EXPECT_EQ('a', s2->GetChar());  // TODO uncomment this
+  s2->SetChar('b');
+
+  StaticField* s3 = statics->GetStaticField(3);
+  EXPECT_EQ('S', s3->GetType());
+//  EXPECT_EQ(65000, s3->GetShort());  // TODO uncomment this
+  s3->SetShort(65001);
+
+  StaticField* s4 = statics->GetStaticField(4);
+  EXPECT_EQ('I', s4->GetType());
+//  EXPECT_EQ(2000000000, s4->GetInt());  // TODO uncomment this
+  s4->SetInt(2000000001);
+
+  StaticField* s5 = statics->GetStaticField(5);
+  EXPECT_EQ('J', s5->GetType());
+//  EXPECT_EQ(0x1234567890abcdefLL, s5->GetLong());  // TODO uncomment this
+  s5->SetLong(0x34567890abcdef12LL);
+
+  StaticField* s6 = statics->GetStaticField(6);
+  EXPECT_EQ('F', s6->GetType());
+//  EXPECT_EQ(0.5, s6->GetFloat());  // TODO uncomment this
+  s6->SetFloat(0.75);
+
+  StaticField* s7 = statics->GetStaticField(7);
+  EXPECT_EQ('D', s7->GetType());
+//  EXPECT_EQ(16777217, s7->GetDouble());  // TODO uncomment this
+  s7->SetDouble(16777219);
+
+  StaticField* s8 = statics->GetStaticField(8);
+  EXPECT_EQ('L', s8->GetType());
+//  EXPECT_TRUE(down_cast<String*>(s8->GetObject())->Equals("android"));  // TODO uncomment this
+  s8->SetObject(String::AllocFromAscii("robot"));
+
+  StaticField* s9 = statics->GetStaticField(9);
+  EXPECT_EQ('[', s9->GetType());
+//  EXPECT_EQ(NULL, s9->GetObject());  // TODO uncomment this
+  s9->SetObject(NULL);
+
+  EXPECT_EQ(false,                s0->GetBoolean());
+  EXPECT_EQ(6,                    s1->GetByte());
+  EXPECT_EQ('b',                  s2->GetChar());
+  EXPECT_EQ(65001,                s3->GetShort());
+  EXPECT_EQ(2000000001,           s4->GetInt());
+  EXPECT_EQ(0x34567890abcdef12LL, s5->GetLong());
+  EXPECT_EQ(0.75,                 s6->GetFloat());
+  EXPECT_EQ(16777219,             s7->GetDouble());
+  EXPECT_TRUE(down_cast<String*>(s8->GetObject())->Equals("robot"));
+}
+
 }  // namespace art