Fixes to make all run-tests except 051-thread work.

- Moved exception delivery into common method DeliverException
- Renamed old DeliverException to QuickDeliverException since it is only
  used by quick
- Fixed null checks for arrays returned by GetReference
- Standardized ArrayStoreException error message
- Added additional sleeps to ensure threads stay alive long enough in
  051-thread, and that <clinit> is complete for 084-class-init

Change-Id: I9ca306896a4bd10f453150fcf3965d9750fa0cbd
diff --git a/src/interpreter/interpreter.cc b/src/interpreter/interpreter.cc
index e68896a..8c217c7 100644
--- a/src/interpreter/interpreter.cc
+++ b/src/interpreter/interpreter.cc
@@ -862,7 +862,7 @@
       }
       case Instruction::THROW: {
         Throwable* t = shadow_frame.GetReference(dec_insn.vA)->AsThrowable();
-        self->SetException(t);
+        self->DeliverException(t);
         break;
       }
       case Instruction::GOTO:
@@ -918,12 +918,13 @@
         break;
       }
       case Instruction::FILL_ARRAY_DATA: {
-        Array* array = shadow_frame.GetReference(dec_insn.vA)->AsArray();
-        if (UNLIKELY(array == NULL)) {
+        Object* obj = shadow_frame.GetReference(dec_insn.vA);
+        if (UNLIKELY(obj == NULL)) {
           Thread::Current()->ThrowNewExceptionF("Ljava/lang/NullPointerException;",
               "null array in FILL_ARRAY_DATA");
           break;
         }
+        Array* array = obj->AsArray();
         DCHECK(array->IsArrayInstance() && !array->IsObjectArray());
         uint32_t dex_pc = inst->GetDexPc(insns);
         const Instruction::ArrayDataPayload* payload =
@@ -1023,151 +1024,150 @@
         break;
       }
       case Instruction::AGET_BOOLEAN: {
-        BooleanArray* a = shadow_frame.GetReference(dec_insn.vB)->AsBooleanArray();
+        Object* a = shadow_frame.GetReference(dec_insn.vB);
         if (UNLIKELY(a == NULL)) {
           ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
           break;
         }
         int32_t index = shadow_frame.GetVReg(dec_insn.vC);
-        shadow_frame.SetVReg(dec_insn.vA, a->Get(index));
+        shadow_frame.SetVReg(dec_insn.vA, a->AsBooleanArray()->Get(index));
         break;
       }
       case Instruction::AGET_BYTE: {
-        ByteArray* a = shadow_frame.GetReference(dec_insn.vB)->AsByteArray();
+        Object* a = shadow_frame.GetReference(dec_insn.vB);
         if (UNLIKELY(a == NULL)) {
           ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
           break;
         }
         int32_t index = shadow_frame.GetVReg(dec_insn.vC);
-        shadow_frame.SetVReg(dec_insn.vA, a->Get(index));
+        shadow_frame.SetVReg(dec_insn.vA, a->AsByteArray()->Get(index));
         break;
       }
       case Instruction::AGET_CHAR: {
-        CharArray* a = shadow_frame.GetReference(dec_insn.vB)->AsCharArray();
+        Object* a = shadow_frame.GetReference(dec_insn.vB);
         if (UNLIKELY(a == NULL)) {
           ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
           break;
         }
         int32_t index = shadow_frame.GetVReg(dec_insn.vC);
-        shadow_frame.SetVReg(dec_insn.vA, a->Get(index));
+        shadow_frame.SetVReg(dec_insn.vA, a->AsCharArray()->Get(index));
         break;
       }
       case Instruction::AGET_SHORT: {
-        ShortArray* a = shadow_frame.GetReference(dec_insn.vB)->AsShortArray();
+        Object* a = shadow_frame.GetReference(dec_insn.vB);
         if (UNLIKELY(a == NULL)) {
           ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
           break;
         }
         int32_t index = shadow_frame.GetVReg(dec_insn.vC);
-        shadow_frame.SetVReg(dec_insn.vA, a->Get(index));
+        shadow_frame.SetVReg(dec_insn.vA, a->AsShortArray()->Get(index));
         break;
       }
       case Instruction::AGET: {
-        IntArray* a = shadow_frame.GetReference(dec_insn.vB)->AsIntArray();
+        Object* a = shadow_frame.GetReference(dec_insn.vB);
         if (UNLIKELY(a == NULL)) {
           ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
           break;
         }
         int32_t index = shadow_frame.GetVReg(dec_insn.vC);
-        shadow_frame.SetVReg(dec_insn.vA, a->Get(index));
+        shadow_frame.SetVReg(dec_insn.vA, a->AsIntArray()->Get(index));
         break;
       }
       case Instruction::AGET_WIDE:  {
-        LongArray* a = shadow_frame.GetReference(dec_insn.vB)->AsLongArray();
+        Object* a = shadow_frame.GetReference(dec_insn.vB);
         if (UNLIKELY(a == NULL)) {
           ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
           break;
         }
         int32_t index = shadow_frame.GetVReg(dec_insn.vC);
-        shadow_frame.SetVRegLong(dec_insn.vA, a->Get(index));
+        shadow_frame.SetVRegLong(dec_insn.vA, a->AsLongArray()->Get(index));
         break;
       }
       case Instruction::AGET_OBJECT: {
-        ObjectArray<Object>* a = shadow_frame.GetReference(dec_insn.vB)->AsObjectArray<Object>();
+        Object* a = shadow_frame.GetReference(dec_insn.vB);
         if (UNLIKELY(a == NULL)) {
           ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
           break;
         }
         int32_t index = shadow_frame.GetVReg(dec_insn.vC);
-        Object* o = a->Get(index);
-        shadow_frame.SetReferenceAndVReg(dec_insn.vA, o);
+        shadow_frame.SetReferenceAndVReg(dec_insn.vA, a->AsObjectArray<Object>()->Get(index));
         break;
       }
       case Instruction::APUT_BOOLEAN: {
         uint8_t val = shadow_frame.GetVReg(dec_insn.vA);
-        BooleanArray* a = shadow_frame.GetReference(dec_insn.vB)->AsBooleanArray();
+        Object* a = shadow_frame.GetReference(dec_insn.vB);
         if (UNLIKELY(a == NULL)) {
           ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
           break;
         }
         int32_t index = shadow_frame.GetVReg(dec_insn.vC);
-        a->Set(index, val);
+        a->AsBooleanArray()->Set(index, val);
         break;
       }
       case Instruction::APUT_BYTE: {
         int8_t val = shadow_frame.GetVReg(dec_insn.vA);
-        ByteArray* a = shadow_frame.GetReference(dec_insn.vB)->AsByteArray();
+        Object* a = shadow_frame.GetReference(dec_insn.vB);
         if (UNLIKELY(a == NULL)) {
           ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
           break;
         }
         int32_t index = shadow_frame.GetVReg(dec_insn.vC);
-        a->Set(index, val);
+        a->AsByteArray()->Set(index, val);
         break;
       }
       case Instruction::APUT_CHAR: {
         uint16_t val = shadow_frame.GetVReg(dec_insn.vA);
-        CharArray* a = shadow_frame.GetReference(dec_insn.vB)->AsCharArray();
+        Object* a = shadow_frame.GetReference(dec_insn.vB);
         if (UNLIKELY(a == NULL)) {
           ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
           break;
         }
         int32_t index = shadow_frame.GetVReg(dec_insn.vC);
-        a->Set(index, val);
+        a->AsCharArray()->Set(index, val);
         break;
       }
       case Instruction::APUT_SHORT: {
         int16_t val = shadow_frame.GetVReg(dec_insn.vA);
-        ShortArray* a = shadow_frame.GetReference(dec_insn.vB)->AsShortArray();
+        Object* a = shadow_frame.GetReference(dec_insn.vB);
         if (UNLIKELY(a == NULL)) {
           ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
           break;
         }
         int32_t index = shadow_frame.GetVReg(dec_insn.vC);
-        a->Set(index, val);
+        a->AsShortArray()->Set(index, val);
         break;
       }
       case Instruction::APUT: {
         int32_t val = shadow_frame.GetVReg(dec_insn.vA);
-        IntArray* a = shadow_frame.GetReference(dec_insn.vB)->AsIntArray();
+        Object* a = shadow_frame.GetReference(dec_insn.vB);
         if (UNLIKELY(a == NULL)) {
           ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
           break;
         }
         int32_t index = shadow_frame.GetVReg(dec_insn.vC);
-        a->Set(index, val);
+        a->AsIntArray()->Set(index, val);
         break;
       }
       case Instruction::APUT_WIDE: {
         int64_t val = shadow_frame.GetVRegLong(dec_insn.vA);
-        LongArray* a = shadow_frame.GetReference(dec_insn.vB)->AsLongArray();
+        Object* a = shadow_frame.GetReference(dec_insn.vB);
         if (UNLIKELY(a == NULL)) {
           ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
           break;
         }
         int32_t index = shadow_frame.GetVReg(dec_insn.vC);
-        a->Set(index, val);
+        a->AsLongArray()->Set(index, val);
         break;
       }
       case Instruction::APUT_OBJECT: {
         Object* val = shadow_frame.GetReference(dec_insn.vA);
-        ObjectArray<Object>* a = shadow_frame.GetReference(dec_insn.vB)->AsObjectArray<Object>();
+        Object* a = shadow_frame.GetReference(dec_insn.vB);
         if (UNLIKELY(a == NULL)) {
           ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
           break;
         }
         int32_t index = shadow_frame.GetVReg(dec_insn.vC);
-        a->Set(index, val);
+        a->AsObjectArray<Object>()->Set(index, val);
         break;
       }
       case Instruction::IGET_BOOLEAN:
@@ -1787,8 +1787,11 @@
     shadow_frame->SetReferenceAndVReg(cur_reg, receiver);
     ++cur_reg;
   } else if (!method->GetDeclaringClass()->IsInitializing()) {
-    Runtime::Current()->GetClassLinker()->EnsureInitialized(method->GetDeclaringClass(),
-                                                            true, true);
+    if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(method->GetDeclaringClass(),
+                                                                 true, true)) {
+      DCHECK(Thread::Current()->IsExceptionPending());
+      return;
+    }
     CHECK(method->GetDeclaringClass()->IsInitializing());
   }
   const char* shorty = mh.GetShorty();