Merge "Parse required options" into dalvik-dev
diff --git a/src/logging.h b/src/logging.h
index bca0cf6..5169e2a 100644
--- a/src/logging.h
+++ b/src/logging.h
@@ -23,7 +23,8 @@
 
 #define CHECK(x) \
   if (!(x)) \
-    LogMessage(__FILE__, __LINE__, FATAL, -1).stream() << "Check failed: " #x
+    LogMessage(__FILE__, __LINE__, FATAL, -1).stream() \
+        << "Check failed: " #x << " "
 
 #define CHECK_OP(LHS, RHS, OP) \
   do { \
@@ -113,7 +114,7 @@
 
 #define LG LOG(INFO)
 
-#define UNIMPLEMENTED(level) LOG(level) << __FUNCTION__ << " unimplemented"
+#define UNIMPLEMENTED(level) LOG(level) << __FUNCTION__ << " unimplemented "
 
 class LogMessage {
  public:
diff --git a/src/object.h b/src/object.h
index 4da6725..da4d6f3 100644
--- a/src/object.h
+++ b/src/object.h
@@ -631,6 +631,7 @@
       Thread* self = Thread::Current();
       self->ThrowNewException("Ljava/lang/ArrayIndexOutOfBoundsException;",
           "length=%i; index=%i", length_, index);
+      return false;
     }
     return true;
   }
@@ -1216,6 +1217,8 @@
 template<class T>
 class PrimitiveArray : public Array {
  public:
+  typedef T ElementType;
+
   static PrimitiveArray<T>* Alloc(size_t length);
 
   const T* GetData() const {
@@ -1228,7 +1231,7 @@
 
   T Get(int32_t i) const {
     if (!IsValidIndex(i)) {
-      return T();
+      return T(0);
     }
     return GetData()[i];
   }
@@ -1281,9 +1284,8 @@
       self->ThrowNewException("Ljava/lang/StringIndexOutOfBoundsException;",
           "length=%i; index=%i", count_, index);
       return 0;
-    } else {
-      return GetCharArray()->Get(index + GetOffset());
     }
+    return GetCharArray()->Get(index + GetOffset());
   }
 
   static String* AllocFromUtf16(int32_t utf16_length,
diff --git a/src/object_test.cc b/src/object_test.cc
index 28aecb0..e11cf07 100644
--- a/src/object_test.cc
+++ b/src/object_test.cc
@@ -65,6 +65,19 @@
   EXPECT_TRUE(oa->Get(0) == oa);
   EXPECT_TRUE(oa->Get(1) == oa);
 
+  Thread* self = Thread::Current();
+  Class* aioobe = class_linker_->FindSystemClass("Ljava/lang/ArrayIndexOutOfBoundsException;");
+
+  EXPECT_TRUE(oa->Get(-1) == NULL);
+  EXPECT_TRUE(self->IsExceptionPending());
+  EXPECT_EQ(aioobe, self->GetException()->GetClass());
+  self->ClearException();
+
+  EXPECT_TRUE(oa->Get(2) == NULL);
+  EXPECT_TRUE(self->IsExceptionPending());
+  EXPECT_EQ(aioobe, self->GetException()->GetClass());
+  self->ClearException();
+
   ASSERT_TRUE(oa->GetClass() != NULL);
   ASSERT_EQ(2U, oa->GetClass()->NumInterfaces());
   EXPECT_EQ(class_linker_->FindSystemClass("Ljava/lang/Cloneable;"),
@@ -73,6 +86,60 @@
             oa->GetClass()->GetInterface(1));
 }
 
+template<typename ArrayT>
+void TestPrimitiveArray(ClassLinker* cl) {
+  typedef typename ArrayT::ElementType T;
+
+  ArrayT* a = ArrayT::Alloc(2);
+  EXPECT_EQ(2, a->GetLength());
+  EXPECT_EQ(0, a->Get(0));
+  EXPECT_EQ(0, a->Get(1));
+  a->Set(0, T(123));
+  EXPECT_EQ(T(123), a->Get(0));
+  EXPECT_EQ(0, a->Get(1));
+  a->Set(1, T(321));
+  EXPECT_EQ(T(123), a->Get(0));
+  EXPECT_EQ(T(321), a->Get(1));
+
+  Thread* self = Thread::Current();
+  Class* aioobe = cl->FindSystemClass("Ljava/lang/ArrayIndexOutOfBoundsException;");
+
+  EXPECT_EQ(0, a->Get(-1));
+  EXPECT_TRUE(self->IsExceptionPending());
+  EXPECT_EQ(aioobe, self->GetException()->GetClass());
+  self->ClearException();
+
+  EXPECT_EQ(0, a->Get(2));
+  EXPECT_TRUE(self->IsExceptionPending());
+  EXPECT_EQ(aioobe, self->GetException()->GetClass());
+  self->ClearException();
+}
+
+TEST_F(ObjectTest, PrimitiveArray_Boolean_Alloc) {
+  TestPrimitiveArray<BooleanArray>(class_linker_);
+}
+TEST_F(ObjectTest, PrimitiveArray_Byte_Alloc) {
+  TestPrimitiveArray<ByteArray>(class_linker_);
+}
+TEST_F(ObjectTest, PrimitiveArray_Char_Alloc) {
+  TestPrimitiveArray<CharArray>(class_linker_);
+}
+TEST_F(ObjectTest, PrimitiveArray_Double_Alloc) {
+  TestPrimitiveArray<DoubleArray>(class_linker_);
+}
+TEST_F(ObjectTest, PrimitiveArray_Float_Alloc) {
+  TestPrimitiveArray<FloatArray>(class_linker_);
+}
+TEST_F(ObjectTest, PrimitiveArray_Int_Alloc) {
+  TestPrimitiveArray<IntArray>(class_linker_);
+}
+TEST_F(ObjectTest, PrimitiveArray_Long_Alloc) {
+  TestPrimitiveArray<LongArray>(class_linker_);
+}
+TEST_F(ObjectTest, PrimitiveArray_Short_Alloc) {
+  TestPrimitiveArray<ShortArray>(class_linker_);
+}
+
 TEST_F(ObjectTest, String) {
   // Test the empty string.
   AssertString(0, "",     "", 0);
diff --git a/src/thread.cc b/src/thread.cc
index 51b72ce..609ae41 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -147,11 +147,11 @@
   // TODO: what if there's already a pending exception?
   // TODO: support the other constructors.
   Method* ctor = exception_class->FindDirectMethod("<init>", "(Ljava/lang/String;)V");
+  CHECK(ctor != NULL);
 
   // TODO: need to *call* the constructor!
   UNIMPLEMENTED(WARNING) << "can't call "
-                         << exception_class->GetDescriptor() << "."
-                         << ctor->GetDescriptor() << " "
+                         << exception_class->GetDescriptor() << ".<init> "
                          << "\"" << msg << "\"";
 
   thread->SetException(exception);