ART: aarch64 jni compiler needs to extend small return types

As aarch64 calling convention does not mandate extension on return
values anymore and leaves the upper bits undefined, the jni compiler
needs to sign- or zero-extend the returned values when necessary.

As three architectures need extension now, refactor this fact into a
flag into a virtual method.

Add tests to JniTest that exercise the required extension.

Change-Id: Idebb7c4dedebb852e58ade63e1c2b1eeced23104
diff --git a/test/JniTest/jni_test.cc b/test/JniTest/jni_test.cc
index 33af94b..024ba53 100644
--- a/test/JniTest/jni_test.cc
+++ b/test/JniTest/jni_test.cc
@@ -137,3 +137,92 @@
   assert(env->GetDirectBufferAddress(byte_buffer) == &buffer[0]);
   assert(env->GetDirectBufferCapacity(byte_buffer) == 0);
 }
+
+constexpr size_t kByteReturnSize = 7;
+jbyte byte_returns[kByteReturnSize] = { 0, 1, 2, 127, -1, -2, -128 };
+
+extern "C" jbyte JNICALL Java_JniTest_byteMethod(JNIEnv* env, jclass klass, jbyte b1, jbyte b2,
+                                                    jbyte b3, jbyte b4, jbyte b5, jbyte b6,
+                                                    jbyte b7, jbyte b8, jbyte b9, jbyte b10) {
+  // We use b1 to drive the output.
+  assert(b2 == 2);
+  assert(b3 == -3);
+  assert(b4 == 4);
+  assert(b5 == -5);
+  assert(b6 == 6);
+  assert(b7 == -7);
+  assert(b8 == 8);
+  assert(b9 == -9);
+  assert(b10 == 10);
+
+  assert(0 <= b1);
+  assert(b1 < static_cast<jbyte>(kByteReturnSize));
+
+  return byte_returns[b1];
+}
+
+constexpr size_t kShortReturnSize = 9;
+jshort short_returns[kShortReturnSize] = { 0, 1, 2, 127, 32767, -1, -2, -128,
+    static_cast<jshort>(0x8000) };
+// The weird static_cast is because short int is only guaranteed down to -32767, not Java's -32768.
+
+extern "C" jshort JNICALL Java_JniTest_shortMethod(JNIEnv* env, jclass klass, jshort s1, jshort s2,
+                                                    jshort s3, jshort s4, jshort s5, jshort s6,
+                                                    jshort s7, jshort s8, jshort s9, jshort s10) {
+  // We use s1 to drive the output.
+  assert(s2 == 2);
+  assert(s3 == -3);
+  assert(s4 == 4);
+  assert(s5 == -5);
+  assert(s6 == 6);
+  assert(s7 == -7);
+  assert(s8 == 8);
+  assert(s9 == -9);
+  assert(s10 == 10);
+
+  assert(0 <= s1);
+  assert(s1 < static_cast<jshort>(kShortReturnSize));
+
+  return short_returns[s1];
+}
+
+extern "C" jboolean JNICALL Java_JniTest_booleanMethod(JNIEnv* env, jclass klass, jboolean b1,
+                                                       jboolean b2, jboolean b3, jboolean b4,
+                                                       jboolean b5, jboolean b6, jboolean b7,
+                                                       jboolean b8, jboolean b9, jboolean b10) {
+  // We use b1 to drive the output.
+  assert(b2 == JNI_TRUE);
+  assert(b3 == JNI_FALSE);
+  assert(b4 == JNI_TRUE);
+  assert(b5 == JNI_FALSE);
+  assert(b6 == JNI_TRUE);
+  assert(b7 == JNI_FALSE);
+  assert(b8 == JNI_TRUE);
+  assert(b9 == JNI_FALSE);
+  assert(b10 == JNI_TRUE);
+
+  assert(b1 == JNI_TRUE || b1 == JNI_FALSE);
+  return b1;
+}
+
+constexpr size_t kCharReturnSize = 8;
+jchar char_returns[kCharReturnSize] = { 0, 1, 2, 127, 255, 256, 15000, 34000 };
+
+extern "C" jchar JNICALL Java_JniTest_charMethod(JNIEnv* env, jclass klacc, jchar c1, jchar c2,
+                                                    jchar c3, jchar c4, jchar c5, jchar c6,
+                                                    jchar c7, jchar c8, jchar c9, jchar c10) {
+  // We use c1 to drive the output.
+  assert(c2 == 'a');
+  assert(c3 == 'b');
+  assert(c4 == 'c');
+  assert(c5 == '0');
+  assert(c6 == '1');
+  assert(c7 == '2');
+  assert(c8 == 1234);
+  assert(c9 == 2345);
+  assert(c10 == 3456);
+
+  assert(c1 < static_cast<jchar>(kCharReturnSize));
+
+  return char_returns[c1];
+}