Initialize ClassLinker from image

Change-Id: Ibaf47b4181f7c6603a8b37e2eba8fa6509c927ed
diff --git a/src/object.h b/src/object.h
index ca09d07..e246dea 100644
--- a/src/object.h
+++ b/src/object.h
@@ -239,6 +239,27 @@
     return down_cast<const Array*>(this);
   }
 
+  bool IsString() const;
+
+  String* AsString() {
+    DCHECK(IsString());
+    return down_cast<String*>(this);
+  }
+
+  bool IsMethod() const;
+
+  Method* AsMethod() {
+    DCHECK(IsMethod());
+    return down_cast<Method*>(this);
+  }
+
+  bool IsField() const;
+
+  Field* AsField() {
+    DCHECK(IsField());
+    return down_cast<Field*>(this);
+  }
+
  public:
   Class* klass_;
 
@@ -285,10 +306,12 @@
 class Field : public AccessibleObject {
  public:
   Class* GetDeclaringClass() const {
+    DCHECK(declaring_class_ != NULL);
     return declaring_class_;
   }
 
   const String* GetName() const {
+    DCHECK(name_ != NULL);
     return name_;
   }
 
@@ -364,14 +387,17 @@
 
   // Returns the method name, e.g. "<init>" or "eatLunch"
   const String* GetName() const {
+    DCHECK(name_ != NULL);
     return name_;
   }
 
   const String* GetSignature() const {
+    DCHECK(signature_ != NULL);
     return signature_;
   }
 
   Class* GetDeclaringClass() const {
+    DCHECK(declaring_class_ != NULL);
     return declaring_class_;
   }
 
@@ -1177,7 +1203,8 @@
 }
 
 inline bool Object::IsClass() const {
-  return klass_ == klass_->klass_;
+  Class* java_lang_Class = klass_->klass_;
+  return klass_ == java_lang_Class;
 }
 
 inline bool Object::IsObjectArray() const {
@@ -1188,6 +1215,18 @@
   return klass_->IsArray();
 }
 
+inline bool Object::IsField() const {
+  Class* java_lang_Class = klass_->klass_;
+  Class* java_lang_reflect_Field = java_lang_Class->GetInstanceField(0)->klass_;
+  return klass_ == java_lang_reflect_Field;
+}
+
+inline bool Object::IsMethod() const {
+  Class* java_lang_Class = klass_->klass_;
+  Class* java_lang_reflect_Method = java_lang_Class->GetDirectMethod(0)->klass_;
+  return klass_ == java_lang_reflect_Method;
+}
+
 inline size_t Object::SizeOf() const {
   if (IsArray()) {
     return AsArray()->SizeOf();
@@ -1236,10 +1275,16 @@
   }
 
   static void SetArrayClass(Class* array_class) {
+    CHECK(array_class_ == NULL);
     CHECK(array_class != NULL);
     array_class_ = array_class;
   }
 
+  static void ResetArrayClass() {
+    CHECK(array_class_ != NULL);
+    array_class_ = NULL;
+  }
+
  private:
   // Location of first element.
   T elements_[0];
@@ -1281,7 +1326,7 @@
   }
 
   static String* AllocFromUtf16(int32_t utf16_length,
-                                uint16_t* utf16_data_in,
+                                const uint16_t* utf16_data_in,
                                 int32_t hash_code) {
     String* string = Alloc(GetJavaLangString(),
                            utf16_length);
@@ -1307,7 +1352,8 @@
     return string;
   }
 
-  static void InitClass(Class* java_lang_String);
+  static void SetClass(Class* java_lang_String);
+  static void ResetClass();
 
   static String* Alloc(Class* java_lang_String,
                        int32_t utf16_length) {
@@ -1489,6 +1535,11 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(String);
 };
 
+inline bool Object::IsString() const {
+  // TODO use "klass_ == String::GetJavaLangString()" instead?
+  return klass_ == klass_->descriptor_->klass_;
+}
+
 inline size_t Class::GetTypeSize(String* descriptor) {
   switch (descriptor->CharAt(0)) {
   case 'B': return 1;  // byte