Implement JNI NewBooleanArray et cetera.

(Primitive types only. NewObjectArray to come...)

Change-Id: I2f54031d96062d666089c91ba40e16028ae21bd4
diff --git a/src/jni_internal.cc b/src/jni_internal.cc
index 23c8273..0e9cb84 100644
--- a/src/jni_internal.cc
+++ b/src/jni_internal.cc
@@ -79,7 +79,7 @@
   return true;
 }
 
-static byte* CreateArgArray(Method* method, va_list ap) {
+byte* CreateArgArray(Method* method, va_list ap) {
   size_t num_bytes = method->NumArgArrayBytes();
   scoped_array<byte> arg_array(new byte[num_bytes]);
   const StringPiece& shorty = method->GetShorty();
@@ -117,7 +117,7 @@
   return arg_array.release();
 }
 
-static byte* CreateArgArray(Method* method, jvalue* args) {
+byte* CreateArgArray(Method* method, jvalue* args) {
   size_t num_bytes = method->NumArgArrayBytes();
   scoped_array<byte> arg_array(new byte[num_bytes]);
   const StringPiece& shorty = method->GetShorty();
@@ -1301,52 +1301,52 @@
   UNIMPLEMENTED(FATAL);
 }
 
+template<typename JniT, typename ArtT>
+JniT NewPrimitiveArray(ScopedJniThreadState& ts, jsize length) {
+  CHECK_GE(length, 0); // TODO: ReportJniError
+  ArtT* result = ArtT::Alloc(length);
+  // TODO: local reference
+  return reinterpret_cast<JniT>(result);
+}
+
 jbooleanArray NewBooleanArray(JNIEnv* env, jsize len) {
   ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
+  return NewPrimitiveArray<jbooleanArray, BooleanArray>(ts, len);
 }
 
 jbyteArray NewByteArray(JNIEnv* env, jsize len) {
   ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
+  return NewPrimitiveArray<jbyteArray, ByteArray>(ts, len);
 }
 
 jcharArray NewCharArray(JNIEnv* env, jsize len) {
   ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-jshortArray NewShortArray(JNIEnv* env, jsize len) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-jintArray NewIntArray(JNIEnv* env, jsize len) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-jlongArray NewLongArray(JNIEnv* env, jsize len) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-jfloatArray NewFloatArray(JNIEnv* env, jsize len) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
+  return NewPrimitiveArray<jcharArray, CharArray>(ts, len);
 }
 
 jdoubleArray NewDoubleArray(JNIEnv* env, jsize len) {
   ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
+  return NewPrimitiveArray<jdoubleArray, DoubleArray>(ts, len);
+}
+
+jfloatArray NewFloatArray(JNIEnv* env, jsize len) {
+  ScopedJniThreadState ts(env);
+  return NewPrimitiveArray<jfloatArray, FloatArray>(ts, len);
+}
+
+jintArray NewIntArray(JNIEnv* env, jsize len) {
+  ScopedJniThreadState ts(env);
+  return NewPrimitiveArray<jintArray, IntArray>(ts, len);
+}
+
+jlongArray NewLongArray(JNIEnv* env, jsize len) {
+  ScopedJniThreadState ts(env);
+  return NewPrimitiveArray<jlongArray, LongArray>(ts, len);
+}
+
+jshortArray NewShortArray(JNIEnv* env, jsize len) {
+  ScopedJniThreadState ts(env);
+  return NewPrimitiveArray<jshortArray, ShortArray>(ts, len);
 }
 
 jboolean* GetBooleanArrayElements(JNIEnv* env,