Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "jni_internal.h"
     18 
     19 #include "android-base/stringprintf.h"
     20 
     21 #include "art_method-inl.h"
     22 #include "common_compiler_test.h"
     23 #include "indirect_reference_table.h"
     24 #include "java_vm_ext.h"
     25 #include "jni_env_ext.h"
     26 #include "mirror/string-inl.h"
     27 #include "nativehelper/scoped_local_ref.h"
     28 #include "scoped_thread_state_change-inl.h"
     29 
     30 namespace art {
     31 
     32 using android::base::StringPrintf;
     33 
     34 // TODO: Convert to CommonRuntimeTest. Currently MakeExecutable is used.
     35 class JniInternalTest : public CommonCompilerTest {
     36  protected:
     37   virtual void SetUp() {
     38     CommonCompilerTest::SetUp();
     39 
     40     vm_ = Runtime::Current()->GetJavaVM();
     41 
     42     // Turn on -verbose:jni for the JNI tests.
     43     // gLogVerbosity.jni = true;
     44 
     45     vm_->AttachCurrentThread(&env_, nullptr);
     46 
     47     ScopedLocalRef<jclass> aioobe(env_,
     48                                   env_->FindClass("java/lang/ArrayIndexOutOfBoundsException"));
     49     CHECK(aioobe.get() != nullptr);
     50     aioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(aioobe.get()));
     51 
     52     ScopedLocalRef<jclass> ase(env_, env_->FindClass("java/lang/ArrayStoreException"));
     53     CHECK(ase.get() != nullptr);
     54     ase_ = reinterpret_cast<jclass>(env_->NewGlobalRef(ase.get()));
     55 
     56     ScopedLocalRef<jclass> sioobe(env_,
     57                                   env_->FindClass("java/lang/StringIndexOutOfBoundsException"));
     58     CHECK(sioobe.get() != nullptr);
     59     sioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(sioobe.get()));
     60   }
     61 
     62   void ExpectException(jclass exception_class) {
     63     ScopedObjectAccess soa(env_);
     64     EXPECT_TRUE(env_->ExceptionCheck())
     65         << mirror::Class::PrettyDescriptor(soa.Decode<mirror::Class>(exception_class));
     66     jthrowable exception = env_->ExceptionOccurred();
     67     EXPECT_NE(nullptr, exception);
     68     env_->ExceptionClear();
     69     EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class));
     70   }
     71 
     72   void CleanUpJniEnv() {
     73     if (aioobe_ != nullptr) {
     74       env_->DeleteGlobalRef(aioobe_);
     75       aioobe_ = nullptr;
     76     }
     77     if (ase_ != nullptr) {
     78       env_->DeleteGlobalRef(ase_);
     79       ase_ = nullptr;
     80     }
     81     if (sioobe_ != nullptr) {
     82       env_->DeleteGlobalRef(sioobe_);
     83       sioobe_ = nullptr;
     84     }
     85   }
     86 
     87   virtual void TearDown() OVERRIDE {
     88     CleanUpJniEnv();
     89     CommonCompilerTest::TearDown();
     90   }
     91 
     92   jclass GetPrimitiveClass(char descriptor) {
     93     ScopedObjectAccess soa(env_);
     94     mirror::Class* c = class_linker_->FindPrimitiveClass(descriptor);
     95     CHECK(c != nullptr);
     96     return soa.AddLocalReference<jclass>(c);
     97   }
     98 
     99   void ExpectClassFound(const char* name) {
    100     EXPECT_NE(env_->FindClass(name), nullptr) << name;
    101     EXPECT_FALSE(env_->ExceptionCheck()) << name;
    102   }
    103 
    104   void ExpectClassNotFound(const char* name, bool check_jni, const char* check_jni_msg,
    105                            CheckJniAbortCatcher* abort_catcher) {
    106     EXPECT_EQ(env_->FindClass(name), nullptr) << name;
    107     if (!check_jni || check_jni_msg == nullptr) {
    108       EXPECT_TRUE(env_->ExceptionCheck()) << name;
    109       env_->ExceptionClear();
    110     } else {
    111       abort_catcher->Check(check_jni_msg);
    112     }
    113   }
    114 
    115   void FindClassTest(bool check_jni) {
    116     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    117     CheckJniAbortCatcher check_jni_abort_catcher;
    118 
    119     // Null argument is always an abort.
    120     env_->FindClass(nullptr);
    121     check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
    122                                             : "name == null");
    123 
    124     // Reference types...
    125     ExpectClassFound("java/lang/String");
    126     // ...for arrays too, where you must include "L;".
    127     ExpectClassFound("[Ljava/lang/String;");
    128     // Primitive arrays are okay too, if the primitive type is valid.
    129     ExpectClassFound("[C");
    130 
    131     // But primitive types aren't allowed...
    132     ExpectClassNotFound("C", check_jni, nullptr, &check_jni_abort_catcher);
    133     ExpectClassNotFound("V", check_jni, nullptr, &check_jni_abort_catcher);
    134     ExpectClassNotFound("K", check_jni, nullptr, &check_jni_abort_catcher);
    135 
    136     if (check_jni) {
    137       // Check JNI will reject invalid class names as aborts but without pending exceptions.
    138       EXPECT_EQ(env_->FindClass("java.lang.String"), nullptr);
    139       EXPECT_FALSE(env_->ExceptionCheck());
    140       check_jni_abort_catcher.Check("illegal class name 'java.lang.String'");
    141 
    142       EXPECT_EQ(env_->FindClass("[Ljava.lang.String;"), nullptr);
    143       EXPECT_FALSE(env_->ExceptionCheck());
    144       check_jni_abort_catcher.Check("illegal class name '[Ljava.lang.String;'");
    145     } else {
    146       // Without check JNI we're tolerant and replace '.' with '/'.
    147       ExpectClassFound("java.lang.String");
    148       ExpectClassFound("[Ljava.lang.String;");
    149     }
    150 
    151     ExpectClassNotFound("Ljava.lang.String;", check_jni, "illegal class name 'Ljava.lang.String;'",
    152                         &check_jni_abort_catcher);
    153     ExpectClassNotFound("[java.lang.String", check_jni, "illegal class name '[java.lang.String'",
    154                         &check_jni_abort_catcher);
    155 
    156     // You can't include the "L;" in a JNI class descriptor.
    157     ExpectClassNotFound("Ljava/lang/String;", check_jni, "illegal class name 'Ljava/lang/String;'",
    158                         &check_jni_abort_catcher);
    159 
    160     // But you must include it for an array of any reference type.
    161     ExpectClassNotFound("[java/lang/String", check_jni, "illegal class name '[java/lang/String'",
    162                         &check_jni_abort_catcher);
    163 
    164     ExpectClassNotFound("[K", check_jni, "illegal class name '[K'", &check_jni_abort_catcher);
    165 
    166     // Void arrays aren't allowed.
    167     ExpectClassNotFound("[V", check_jni, "illegal class name '[V'", &check_jni_abort_catcher);
    168 
    169     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    170   }
    171 
    172   void GetFieldIdBadArgumentTest(bool check_jni) {
    173     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    174     CheckJniAbortCatcher check_jni_abort_catcher;
    175 
    176     jclass c = env_->FindClass("java/lang/String");
    177     ASSERT_NE(c, nullptr);
    178 
    179     jfieldID fid = env_->GetFieldID(nullptr, "count", "I");
    180     EXPECT_EQ(nullptr, fid);
    181     check_jni_abort_catcher.Check(check_jni ? "GetFieldID received NULL jclass"
    182                                             : "java_class == null");
    183     fid = env_->GetFieldID(c, nullptr, "I");
    184     EXPECT_EQ(nullptr, fid);
    185     check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
    186                                             : "name == null");
    187     fid = env_->GetFieldID(c, "count", nullptr);
    188     EXPECT_EQ(nullptr, fid);
    189     check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
    190                                             : "sig == null");
    191 
    192     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    193   }
    194 
    195   void GetStaticFieldIdBadArgumentTest(bool check_jni) {
    196     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    197     CheckJniAbortCatcher check_jni_abort_catcher;
    198 
    199     jclass c = env_->FindClass("java/lang/String");
    200     ASSERT_NE(c, nullptr);
    201 
    202     jfieldID fid = env_->GetStaticFieldID(nullptr, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
    203     EXPECT_EQ(nullptr, fid);
    204     check_jni_abort_catcher.Check(check_jni ? "GetStaticFieldID received NULL jclass"
    205                                             : "java_class == null");
    206     fid = env_->GetStaticFieldID(c, nullptr, "Ljava/util/Comparator;");
    207     EXPECT_EQ(nullptr, fid);
    208     check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
    209                                             : "name == null");
    210     fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", nullptr);
    211     EXPECT_EQ(nullptr, fid);
    212     check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
    213                                             : "sig == null");
    214 
    215     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    216   }
    217 
    218   void GetMethodIdBadArgumentTest(bool check_jni) {
    219     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    220     CheckJniAbortCatcher check_jni_abort_catcher;
    221 
    222     jmethodID method = env_->GetMethodID(nullptr, "<init>", "(Ljava/lang/String;)V");
    223     EXPECT_EQ(nullptr, method);
    224     check_jni_abort_catcher.Check(check_jni ? "GetMethodID received NULL jclass"
    225                                             : "java_class == null");
    226     jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
    227     ASSERT_TRUE(jlnsme != nullptr);
    228     method = env_->GetMethodID(jlnsme, nullptr, "(Ljava/lang/String;)V");
    229     EXPECT_EQ(nullptr, method);
    230     check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
    231                                             : "name == null");
    232     method = env_->GetMethodID(jlnsme, "<init>", nullptr);
    233     EXPECT_EQ(nullptr, method);
    234     check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
    235                                             : "sig == null");
    236 
    237     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    238   }
    239 
    240   void GetStaticMethodIdBadArgumentTest(bool check_jni) {
    241     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    242     CheckJniAbortCatcher check_jni_abort_catcher;
    243 
    244     jmethodID method = env_->GetStaticMethodID(nullptr, "valueOf", "(I)Ljava/lang/String;");
    245     EXPECT_EQ(nullptr, method);
    246     check_jni_abort_catcher.Check(check_jni ? "GetStaticMethodID received NULL jclass"
    247                                             : "java_class == null");
    248     jclass jlstring = env_->FindClass("java/lang/String");
    249     method = env_->GetStaticMethodID(jlstring, nullptr, "(I)Ljava/lang/String;");
    250     EXPECT_EQ(nullptr, method);
    251     check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
    252                                             : "name == null");
    253     method = env_->GetStaticMethodID(jlstring, "valueOf", nullptr);
    254     EXPECT_EQ(nullptr, method);
    255     check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
    256                                             : "sig == null");
    257 
    258     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    259   }
    260 
    261   void GetFromReflectedField_ToReflectedFieldBadArgumentTest(bool check_jni) {
    262     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    263     CheckJniAbortCatcher check_jni_abort_catcher;
    264 
    265     jclass c = env_->FindClass("java/lang/String");
    266     ASSERT_NE(c, nullptr);
    267     jfieldID fid = env_->GetFieldID(c, "count", "I");
    268     ASSERT_NE(fid, nullptr);
    269 
    270     // Check class argument for null argument, not checked in non-check JNI.
    271     jobject field = env_->ToReflectedField(nullptr, fid, JNI_FALSE);
    272     if (check_jni) {
    273       EXPECT_EQ(field, nullptr);
    274       check_jni_abort_catcher.Check("ToReflectedField received NULL jclass");
    275     } else {
    276       EXPECT_NE(field, nullptr);
    277     }
    278 
    279     field = env_->ToReflectedField(c, nullptr, JNI_FALSE);
    280     EXPECT_EQ(field, nullptr);
    281     check_jni_abort_catcher.Check(check_jni ? "jfieldID was NULL"
    282                                             : "fid == null");
    283 
    284     fid = env_->FromReflectedField(nullptr);
    285     ASSERT_EQ(fid, nullptr);
    286     check_jni_abort_catcher.Check(check_jni ? "expected non-null java.lang.reflect.Field"
    287                                             : "jlr_field == null");
    288 
    289     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    290   }
    291 
    292   void GetFromReflectedMethod_ToReflectedMethodBadArgumentTest(bool check_jni) {
    293     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    294     CheckJniAbortCatcher check_jni_abort_catcher;
    295 
    296     jclass c = env_->FindClass("java/lang/String");
    297     ASSERT_NE(c, nullptr);
    298     jmethodID mid = env_->GetMethodID(c, "<init>", "()V");
    299     ASSERT_NE(mid, nullptr);
    300 
    301     // Check class argument for null argument, not checked in non-check JNI.
    302     jobject method = env_->ToReflectedMethod(nullptr, mid, JNI_FALSE);
    303     if (check_jni) {
    304       EXPECT_EQ(method, nullptr);
    305       check_jni_abort_catcher.Check("ToReflectedMethod received NULL jclass");
    306     } else {
    307       EXPECT_NE(method, nullptr);
    308     }
    309 
    310     method = env_->ToReflectedMethod(c, nullptr, JNI_FALSE);
    311     EXPECT_EQ(method, nullptr);
    312     check_jni_abort_catcher.Check(check_jni ? "jmethodID was NULL"
    313                                             : "mid == null");
    314     mid = env_->FromReflectedMethod(method);
    315     ASSERT_EQ(mid, nullptr);
    316     check_jni_abort_catcher.Check(check_jni ? "expected non-null method" : "jlr_method == null");
    317 
    318     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    319   }
    320 
    321   void RegisterAndUnregisterNativesBadArguments(bool check_jni,
    322                                                 CheckJniAbortCatcher* check_jni_abort_catcher) {
    323     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    324     // Passing a class of null is a failure.
    325     {
    326       JNINativeMethod methods[] = { };
    327       EXPECT_EQ(env_->RegisterNatives(nullptr, methods, 0), JNI_ERR);
    328       check_jni_abort_catcher->Check(check_jni ? "RegisterNatives received NULL jclass"
    329                                                : "java_class == null");
    330     }
    331 
    332     // Passing methods as null is a failure.
    333     jclass jlobject = env_->FindClass("java/lang/Object");
    334     EXPECT_EQ(env_->RegisterNatives(jlobject, nullptr, 1), JNI_ERR);
    335     check_jni_abort_catcher->Check("methods == null");
    336 
    337     // Unregisters null is a failure.
    338     EXPECT_EQ(env_->UnregisterNatives(nullptr), JNI_ERR);
    339     check_jni_abort_catcher->Check(check_jni ? "UnregisterNatives received NULL jclass"
    340                                              : "java_class == null");
    341 
    342     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    343   }
    344 
    345 
    346   void GetPrimitiveArrayElementsOfWrongType(bool check_jni) {
    347     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    348     CheckJniAbortCatcher jni_abort_catcher;
    349 
    350     jbooleanArray array = env_->NewBooleanArray(10);
    351     jboolean is_copy;
    352     EXPECT_EQ(env_->GetByteArrayElements(reinterpret_cast<jbyteArray>(array), &is_copy), nullptr);
    353     jni_abort_catcher.Check(
    354         check_jni ? "incompatible array type boolean[] expected byte[]"
    355             : "attempt to get byte primitive array elements with an object of type boolean[]");
    356     EXPECT_EQ(env_->GetShortArrayElements(reinterpret_cast<jshortArray>(array), &is_copy), nullptr);
    357     jni_abort_catcher.Check(
    358         check_jni ? "incompatible array type boolean[] expected short[]"
    359             : "attempt to get short primitive array elements with an object of type boolean[]");
    360     EXPECT_EQ(env_->GetCharArrayElements(reinterpret_cast<jcharArray>(array), &is_copy), nullptr);
    361     jni_abort_catcher.Check(
    362         check_jni ? "incompatible array type boolean[] expected char[]"
    363             : "attempt to get char primitive array elements with an object of type boolean[]");
    364     EXPECT_EQ(env_->GetIntArrayElements(reinterpret_cast<jintArray>(array), &is_copy), nullptr);
    365     jni_abort_catcher.Check(
    366         check_jni ? "incompatible array type boolean[] expected int[]"
    367             : "attempt to get int primitive array elements with an object of type boolean[]");
    368     EXPECT_EQ(env_->GetLongArrayElements(reinterpret_cast<jlongArray>(array), &is_copy), nullptr);
    369     jni_abort_catcher.Check(
    370         check_jni ? "incompatible array type boolean[] expected long[]"
    371             : "attempt to get long primitive array elements with an object of type boolean[]");
    372     EXPECT_EQ(env_->GetFloatArrayElements(reinterpret_cast<jfloatArray>(array), &is_copy), nullptr);
    373     jni_abort_catcher.Check(
    374         check_jni ? "incompatible array type boolean[] expected float[]"
    375             : "attempt to get float primitive array elements with an object of type boolean[]");
    376     EXPECT_EQ(env_->GetDoubleArrayElements(reinterpret_cast<jdoubleArray>(array), &is_copy), nullptr);
    377     jni_abort_catcher.Check(
    378         check_jni ? "incompatible array type boolean[] expected double[]"
    379             : "attempt to get double primitive array elements with an object of type boolean[]");
    380     jbyteArray array2 = env_->NewByteArray(10);
    381     EXPECT_EQ(env_->GetBooleanArrayElements(reinterpret_cast<jbooleanArray>(array2), &is_copy),
    382               nullptr);
    383     jni_abort_catcher.Check(
    384         check_jni ? "incompatible array type byte[] expected boolean[]"
    385             : "attempt to get boolean primitive array elements with an object of type byte[]");
    386     jobject object = env_->NewStringUTF("Test String");
    387     EXPECT_EQ(env_->GetBooleanArrayElements(reinterpret_cast<jbooleanArray>(object), &is_copy),
    388               nullptr);
    389     jni_abort_catcher.Check(
    390         check_jni ? "jarray argument has non-array type: java.lang.String"
    391         : "attempt to get boolean primitive array elements with an object of type java.lang.String");
    392 
    393     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    394   }
    395 
    396   void ReleasePrimitiveArrayElementsOfWrongType(bool check_jni) {
    397     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    398     CheckJniAbortCatcher jni_abort_catcher;
    399     {
    400       jbooleanArray array = env_->NewBooleanArray(10);
    401       ASSERT_TRUE(array != nullptr);
    402       jboolean is_copy;
    403       jboolean* elements = env_->GetBooleanArrayElements(array, &is_copy);
    404       ASSERT_TRUE(elements != nullptr);
    405       env_->ReleaseByteArrayElements(reinterpret_cast<jbyteArray>(array),
    406                                      reinterpret_cast<jbyte*>(elements), 0);
    407       jni_abort_catcher.Check(
    408           check_jni ? "incompatible array type boolean[] expected byte[]"
    409               : "attempt to release byte primitive array elements with an object of type boolean[]");
    410       env_->ReleaseShortArrayElements(reinterpret_cast<jshortArray>(array),
    411                                       reinterpret_cast<jshort*>(elements), 0);
    412       jni_abort_catcher.Check(
    413           check_jni ? "incompatible array type boolean[] expected short[]"
    414               : "attempt to release short primitive array elements with an object of type boolean[]");
    415       env_->ReleaseCharArrayElements(reinterpret_cast<jcharArray>(array),
    416                                      reinterpret_cast<jchar*>(elements), 0);
    417       jni_abort_catcher.Check(
    418           check_jni ? "incompatible array type boolean[] expected char[]"
    419               : "attempt to release char primitive array elements with an object of type boolean[]");
    420       env_->ReleaseIntArrayElements(reinterpret_cast<jintArray>(array),
    421                                     reinterpret_cast<jint*>(elements), 0);
    422       jni_abort_catcher.Check(
    423           check_jni ? "incompatible array type boolean[] expected int[]"
    424               : "attempt to release int primitive array elements with an object of type boolean[]");
    425       env_->ReleaseLongArrayElements(reinterpret_cast<jlongArray>(array),
    426                                      reinterpret_cast<jlong*>(elements), 0);
    427       jni_abort_catcher.Check(
    428           check_jni ? "incompatible array type boolean[] expected long[]"
    429               : "attempt to release long primitive array elements with an object of type boolean[]");
    430       env_->ReleaseFloatArrayElements(reinterpret_cast<jfloatArray>(array),
    431                                       reinterpret_cast<jfloat*>(elements), 0);
    432       jni_abort_catcher.Check(
    433           check_jni ? "incompatible array type boolean[] expected float[]"
    434               : "attempt to release float primitive array elements with an object of type boolean[]");
    435       env_->ReleaseDoubleArrayElements(reinterpret_cast<jdoubleArray>(array),
    436                                        reinterpret_cast<jdouble*>(elements), 0);
    437       jni_abort_catcher.Check(
    438           check_jni ? "incompatible array type boolean[] expected double[]"
    439               : "attempt to release double primitive array elements with an object of type boolean[]");
    440 
    441       // Don't leak the elements array.
    442       env_->ReleaseBooleanArrayElements(array, elements, 0);
    443     }
    444     {
    445       jbyteArray array = env_->NewByteArray(10);
    446       jboolean is_copy;
    447       jbyte* elements = env_->GetByteArrayElements(array, &is_copy);
    448 
    449       env_->ReleaseBooleanArrayElements(reinterpret_cast<jbooleanArray>(array),
    450                                         reinterpret_cast<jboolean*>(elements), 0);
    451       jni_abort_catcher.Check(
    452           check_jni ? "incompatible array type byte[] expected boolean[]"
    453               : "attempt to release boolean primitive array elements with an object of type byte[]");
    454       jobject object = env_->NewStringUTF("Test String");
    455       env_->ReleaseBooleanArrayElements(reinterpret_cast<jbooleanArray>(object),
    456                                         reinterpret_cast<jboolean*>(elements), 0);
    457       jni_abort_catcher.Check(
    458           check_jni ? "jarray argument has non-array type: java.lang.String"
    459               : "attempt to release boolean primitive array elements with an object of type "
    460               "java.lang.String");
    461 
    462       // Don't leak the elements array.
    463       env_->ReleaseByteArrayElements(array, elements, 0);
    464     }
    465     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    466   }
    467 
    468   void GetReleasePrimitiveArrayCriticalOfWrongType(bool check_jni) {
    469     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    470     CheckJniAbortCatcher jni_abort_catcher;
    471 
    472     jobject object = env_->NewStringUTF("Test String");
    473     jboolean is_copy;
    474     void* elements = env_->GetPrimitiveArrayCritical(reinterpret_cast<jarray>(object), &is_copy);
    475     jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String"
    476         : "expected primitive array, given java.lang.String");
    477     env_->ReleasePrimitiveArrayCritical(reinterpret_cast<jarray>(object), elements, 0);
    478     jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String"
    479         : "expected primitive array, given java.lang.String");
    480 
    481     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    482   }
    483 
    484   void GetPrimitiveArrayRegionElementsOfWrongType(bool check_jni) {
    485     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    486     CheckJniAbortCatcher jni_abort_catcher;
    487     constexpr size_t kLength = 10;
    488     jbooleanArray array = env_->NewBooleanArray(kLength);
    489     ASSERT_TRUE(array != nullptr);
    490     jboolean elements[kLength];
    491     env_->GetByteArrayRegion(reinterpret_cast<jbyteArray>(array), 0, kLength,
    492                              reinterpret_cast<jbyte*>(elements));
    493     jni_abort_catcher.Check(
    494         check_jni ? "incompatible array type boolean[] expected byte[]"
    495             : "attempt to get region of byte primitive array elements with an object of type boolean[]");
    496     env_->GetShortArrayRegion(reinterpret_cast<jshortArray>(array), 0, kLength,
    497                               reinterpret_cast<jshort*>(elements));
    498     jni_abort_catcher.Check(
    499         check_jni ? "incompatible array type boolean[] expected short[]"
    500             : "attempt to get region of short primitive array elements with an object of type boolean[]");
    501     env_->GetCharArrayRegion(reinterpret_cast<jcharArray>(array), 0, kLength,
    502                              reinterpret_cast<jchar*>(elements));
    503     jni_abort_catcher.Check(
    504         check_jni ? "incompatible array type boolean[] expected char[]"
    505             : "attempt to get region of char primitive array elements with an object of type boolean[]");
    506     env_->GetIntArrayRegion(reinterpret_cast<jintArray>(array), 0, kLength,
    507                             reinterpret_cast<jint*>(elements));
    508     jni_abort_catcher.Check(
    509         check_jni ? "incompatible array type boolean[] expected int[]"
    510             : "attempt to get region of int primitive array elements with an object of type boolean[]");
    511     env_->GetLongArrayRegion(reinterpret_cast<jlongArray>(array), 0, kLength,
    512                              reinterpret_cast<jlong*>(elements));
    513     jni_abort_catcher.Check(
    514         check_jni ? "incompatible array type boolean[] expected long[]"
    515             : "attempt to get region of long primitive array elements with an object of type boolean[]");
    516     env_->GetFloatArrayRegion(reinterpret_cast<jfloatArray>(array), 0, kLength,
    517                               reinterpret_cast<jfloat*>(elements));
    518     jni_abort_catcher.Check(
    519         check_jni ? "incompatible array type boolean[] expected float[]"
    520             : "attempt to get region of float primitive array elements with an object of type boolean[]");
    521     env_->GetDoubleArrayRegion(reinterpret_cast<jdoubleArray>(array), 0, kLength,
    522                                reinterpret_cast<jdouble*>(elements));
    523     jni_abort_catcher.Check(
    524         check_jni ? "incompatible array type boolean[] expected double[]"
    525             : "attempt to get region of double primitive array elements with an object of type boolean[]");
    526     jbyteArray array2 = env_->NewByteArray(10);
    527     env_->GetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(array2), 0, kLength,
    528                                 reinterpret_cast<jboolean*>(elements));
    529     jni_abort_catcher.Check(
    530         check_jni ? "incompatible array type byte[] expected boolean[]"
    531             : "attempt to get region of boolean primitive array elements with an object of type byte[]");
    532     jobject object = env_->NewStringUTF("Test String");
    533     env_->GetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(object), 0, kLength,
    534                                 reinterpret_cast<jboolean*>(elements));
    535     jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String"
    536         : "attempt to get region of boolean primitive array elements with an object of type "
    537           "java.lang.String");
    538 
    539     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    540   }
    541 
    542   void SetPrimitiveArrayRegionElementsOfWrongType(bool check_jni) {
    543     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    544     CheckJniAbortCatcher jni_abort_catcher;
    545     constexpr size_t kLength = 10;
    546     jbooleanArray array = env_->NewBooleanArray(kLength);
    547     ASSERT_TRUE(array != nullptr);
    548     jboolean elements[kLength];
    549     env_->SetByteArrayRegion(reinterpret_cast<jbyteArray>(array), 0, kLength,
    550                              reinterpret_cast<jbyte*>(elements));
    551     jni_abort_catcher.Check(
    552         check_jni ? "incompatible array type boolean[] expected byte[]"
    553             : "attempt to set region of byte primitive array elements with an object of type boolean[]");
    554     env_->SetShortArrayRegion(reinterpret_cast<jshortArray>(array), 0, kLength,
    555                               reinterpret_cast<jshort*>(elements));
    556     jni_abort_catcher.Check(
    557         check_jni ? "incompatible array type boolean[] expected short[]"
    558             : "attempt to set region of short primitive array elements with an object of type boolean[]");
    559     env_->SetCharArrayRegion(reinterpret_cast<jcharArray>(array), 0, kLength,
    560                              reinterpret_cast<jchar*>(elements));
    561     jni_abort_catcher.Check(
    562         check_jni ? "incompatible array type boolean[] expected char[]"
    563             : "attempt to set region of char primitive array elements with an object of type boolean[]");
    564     env_->SetIntArrayRegion(reinterpret_cast<jintArray>(array), 0, kLength,
    565                             reinterpret_cast<jint*>(elements));
    566     jni_abort_catcher.Check(
    567         check_jni ? "incompatible array type boolean[] expected int[]"
    568             : "attempt to set region of int primitive array elements with an object of type boolean[]");
    569     env_->SetLongArrayRegion(reinterpret_cast<jlongArray>(array), 0, kLength,
    570                              reinterpret_cast<jlong*>(elements));
    571     jni_abort_catcher.Check(
    572         check_jni ? "incompatible array type boolean[] expected long[]"
    573             : "attempt to set region of long primitive array elements with an object of type boolean[]");
    574     env_->SetFloatArrayRegion(reinterpret_cast<jfloatArray>(array), 0, kLength,
    575                               reinterpret_cast<jfloat*>(elements));
    576     jni_abort_catcher.Check(
    577         check_jni ? "incompatible array type boolean[] expected float[]"
    578             : "attempt to set region of float primitive array elements with an object of type boolean[]");
    579     env_->SetDoubleArrayRegion(reinterpret_cast<jdoubleArray>(array), 0, kLength,
    580                                reinterpret_cast<jdouble*>(elements));
    581     jni_abort_catcher.Check(
    582         check_jni ? "incompatible array type boolean[] expected double[]"
    583             : "attempt to set region of double primitive array elements with an object of type boolean[]");
    584     jbyteArray array2 = env_->NewByteArray(10);
    585     env_->SetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(array2), 0, kLength,
    586                                 reinterpret_cast<jboolean*>(elements));
    587     jni_abort_catcher.Check(
    588         check_jni ? "incompatible array type byte[] expected boolean[]"
    589             : "attempt to set region of boolean primitive array elements with an object of type byte[]");
    590     jobject object = env_->NewStringUTF("Test String");
    591     env_->SetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(object), 0, kLength,
    592                                 reinterpret_cast<jboolean*>(elements));
    593     jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String"
    594         : "attempt to set region of boolean primitive array elements with an object of type "
    595           "java.lang.String");
    596     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    597   }
    598 
    599   void NewObjectArrayBadArguments(bool check_jni) {
    600     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
    601     CheckJniAbortCatcher jni_abort_catcher;
    602 
    603     jclass element_class = env_->FindClass("java/lang/String");
    604     ASSERT_NE(element_class, nullptr);
    605 
    606     env_->NewObjectArray(-1, element_class, nullptr);
    607     jni_abort_catcher.Check(check_jni ? "negative jsize: -1" : "negative array length: -1");
    608 
    609     env_->NewObjectArray(std::numeric_limits<jint>::min(), element_class, nullptr);
    610     jni_abort_catcher.Check(check_jni ? "negative jsize: -2147483648"
    611         : "negative array length: -2147483648");
    612 
    613     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
    614   }
    615 
    616   void SetUpForTest(bool direct, const char* method_name, const char* method_sig,
    617                     void* native_fnptr) {
    618     // Initialize class loader and set generic JNI entrypoint.
    619     // Note: this code is adapted from the jni_compiler_test, and taken with minimal modifications.
    620     if (!runtime_->IsStarted()) {
    621       {
    622         ScopedObjectAccess soa(Thread::Current());
    623         class_loader_ = LoadDex("MyClassNatives");
    624         StackHandleScope<1> hs(soa.Self());
    625         Handle<mirror::ClassLoader> loader(
    626             hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_)));
    627         mirror::Class* c = class_linker_->FindClass(soa.Self(), "LMyClassNatives;", loader);
    628         const auto pointer_size = class_linker_->GetImagePointerSize();
    629         ArtMethod* method = c->FindClassMethod(method_name, method_sig, pointer_size);
    630         ASSERT_TRUE(method != nullptr) << method_name << " " << method_sig;
    631         ASSERT_EQ(direct, method->IsDirect());
    632         method->SetEntryPointFromQuickCompiledCode(class_linker_->GetRuntimeQuickGenericJniStub());
    633       }
    634       // Start runtime.
    635       Thread::Current()->TransitionFromSuspendedToRunnable();
    636       bool started = runtime_->Start();
    637       CHECK(started);
    638     }
    639     // JNI operations after runtime start.
    640     env_ = Thread::Current()->GetJniEnv();
    641     jklass_ = env_->FindClass("MyClassNatives");
    642     ASSERT_TRUE(jklass_ != nullptr) << method_name << " " << method_sig;
    643 
    644     if (direct) {
    645       jmethod_ = env_->GetStaticMethodID(jklass_, method_name, method_sig);
    646     } else {
    647       jmethod_ = env_->GetMethodID(jklass_, method_name, method_sig);
    648     }
    649     ASSERT_TRUE(jmethod_ != nullptr) << method_name << " " << method_sig;
    650 
    651     if (native_fnptr != nullptr) {
    652       JNINativeMethod methods[] = { { method_name, method_sig, native_fnptr } };
    653       ASSERT_EQ(JNI_OK, env_->RegisterNatives(jklass_, methods, 1))
    654           << method_name << " " << method_sig;
    655     } else {
    656       env_->UnregisterNatives(jklass_);
    657     }
    658 
    659     jmethodID constructor = env_->GetMethodID(jklass_, "<init>", "()V");
    660     jobj_ = env_->NewObject(jklass_, constructor);
    661     ASSERT_TRUE(jobj_ != nullptr) << method_name << " " << method_sig;
    662   }
    663 
    664   JavaVMExt* vm_;
    665   JNIEnv* env_;
    666   jclass aioobe_;
    667   jclass ase_;
    668   jclass sioobe_;
    669 
    670   jclass jklass_;
    671   jobject jobj_;
    672   jobject class_loader_;
    673   jmethodID jmethod_;
    674 };
    675 
    676 TEST_F(JniInternalTest, AllocObject) {
    677   jclass c = env_->FindClass("java/lang/String");
    678   ASSERT_NE(c, nullptr);
    679   jobject o = env_->AllocObject(c);
    680   ASSERT_NE(o, nullptr);
    681 
    682   // We have an instance of the class we asked for...
    683   ASSERT_TRUE(env_->IsInstanceOf(o, c));
    684   // ...whose fields haven't been initialized because
    685   // we didn't call a constructor.
    686   // Even with string compression empty string has `count == 0`.
    687   ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "count", "I")));
    688 }
    689 
    690 TEST_F(JniInternalTest, GetVersion) {
    691   ASSERT_EQ(JNI_VERSION_1_6, env_->GetVersion());
    692 }
    693 
    694 TEST_F(JniInternalTest, FindClass) {
    695   // This tests leads to warnings in the log.
    696   ScopedLogSeverity sls(LogSeverity::ERROR);
    697 
    698   FindClassTest(false);
    699   FindClassTest(true);
    700 }
    701 
    702 TEST_F(JniInternalTest, GetFieldID) {
    703   jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
    704   ASSERT_NE(jlnsfe, nullptr);
    705   jclass c = env_->FindClass("java/lang/String");
    706   ASSERT_NE(c, nullptr);
    707 
    708   // Wrong type.
    709   jfieldID fid = env_->GetFieldID(c, "count", "J");
    710   EXPECT_EQ(nullptr, fid);
    711   ExpectException(jlnsfe);
    712 
    713   // Wrong type where type doesn't exist.
    714   fid = env_->GetFieldID(c, "count", "Lrod/jane/freddy;");
    715   EXPECT_EQ(nullptr, fid);
    716   ExpectException(jlnsfe);
    717 
    718   // Wrong name.
    719   fid = env_->GetFieldID(c, "Count", "I");
    720   EXPECT_EQ(nullptr, fid);
    721   ExpectException(jlnsfe);
    722 
    723   // Good declared field lookup.
    724   fid = env_->GetFieldID(c, "count", "I");
    725   EXPECT_NE(nullptr, fid);
    726   EXPECT_FALSE(env_->ExceptionCheck());
    727 
    728   // Good superclass field lookup.
    729   c = env_->FindClass("java/lang/StringBuilder");
    730   fid = env_->GetFieldID(c, "count", "I");
    731   EXPECT_NE(nullptr, fid);
    732   EXPECT_NE(fid, nullptr);
    733   EXPECT_FALSE(env_->ExceptionCheck());
    734 
    735   // Not instance.
    736   fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
    737   EXPECT_EQ(nullptr, fid);
    738   ExpectException(jlnsfe);
    739 
    740   // Bad arguments.
    741   GetFieldIdBadArgumentTest(false);
    742   GetFieldIdBadArgumentTest(true);
    743 }
    744 
    745 TEST_F(JniInternalTest, GetStaticFieldID) {
    746   jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
    747   ASSERT_NE(jlnsfe, nullptr);
    748   jclass c = env_->FindClass("java/lang/String");
    749   ASSERT_NE(c, nullptr);
    750 
    751   // Wrong type.
    752   jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J");
    753   EXPECT_EQ(nullptr, fid);
    754   ExpectException(jlnsfe);
    755 
    756   // Wrong type where type doesn't exist.
    757   fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Lrod/jane/freddy;");
    758   EXPECT_EQ(nullptr, fid);
    759   ExpectException(jlnsfe);
    760 
    761   // Wrong name.
    762   fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
    763   EXPECT_EQ(nullptr, fid);
    764   ExpectException(jlnsfe);
    765 
    766   // Good declared field lookup.
    767   fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
    768   EXPECT_NE(nullptr, fid);
    769   EXPECT_NE(fid, nullptr);
    770   EXPECT_FALSE(env_->ExceptionCheck());
    771 
    772   // Not static.
    773   fid = env_->GetStaticFieldID(c, "count", "I");
    774   EXPECT_EQ(nullptr, fid);
    775   ExpectException(jlnsfe);
    776 
    777   // Bad arguments.
    778   GetStaticFieldIdBadArgumentTest(false);
    779   GetStaticFieldIdBadArgumentTest(true);
    780 }
    781 
    782 TEST_F(JniInternalTest, GetMethodID) {
    783   jclass jlobject = env_->FindClass("java/lang/Object");
    784   jclass jlstring = env_->FindClass("java/lang/String");
    785   jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
    786   jclass jncrbc = env_->FindClass("java/nio/channels/ReadableByteChannel");
    787 
    788   // Sanity check that no exceptions are pending.
    789   ASSERT_FALSE(env_->ExceptionCheck());
    790 
    791   // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
    792   // a pending exception.
    793   jmethodID method = env_->GetMethodID(jlobject, "foo", "()V");
    794   EXPECT_EQ(nullptr, method);
    795   ExpectException(jlnsme);
    796 
    797   // Check that java.lang.Object.equals() does exist.
    798   method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
    799   EXPECT_NE(nullptr, method);
    800   EXPECT_FALSE(env_->ExceptionCheck());
    801 
    802   // Check that GetMethodID for java.lang.String.valueOf(int) fails as the
    803   // method is static.
    804   method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
    805   EXPECT_EQ(nullptr, method);
    806   ExpectException(jlnsme);
    807 
    808   // Check that GetMethodID for java.lang.NoSuchMethodError.<init>(String) finds the constructor.
    809   method = env_->GetMethodID(jlnsme, "<init>", "(Ljava/lang/String;)V");
    810   EXPECT_NE(nullptr, method);
    811   EXPECT_FALSE(env_->ExceptionCheck());
    812 
    813   // Check that GetMethodID can find a interface method inherited from another interface.
    814   method = env_->GetMethodID(jncrbc, "close", "()V");
    815   EXPECT_NE(nullptr, method);
    816   EXPECT_FALSE(env_->ExceptionCheck());
    817 
    818   // Bad arguments.
    819   GetMethodIdBadArgumentTest(false);
    820   GetMethodIdBadArgumentTest(true);
    821 }
    822 
    823 TEST_F(JniInternalTest, CallVoidMethodNullReceiver) {
    824   jclass jlobject = env_->FindClass("java/lang/Object");
    825   jmethodID method;
    826 
    827   // Check that GetMethodID for java.lang.NoSuchMethodError.<init>(String) finds the constructor.
    828   method = env_->GetMethodID(jlobject, "<init>", "()V");
    829   EXPECT_NE(nullptr, method);
    830   EXPECT_FALSE(env_->ExceptionCheck());
    831 
    832   // Null object to CallVoidMethod.
    833   CheckJniAbortCatcher check_jni_abort_catcher;
    834   env_->CallVoidMethod(nullptr, method);
    835   check_jni_abort_catcher.Check("null");
    836 }
    837 
    838 TEST_F(JniInternalTest, CallVarArgMethodBadPrimitive) {
    839   // Check that bad primitive values cause check JNI to abort when
    840   // passed out-of-range primitive value var args. As var args can't
    841   // differentiate type sizes less than an int, and this isn't
    842   // corrected by JNI, this helps ensure JNI code is valid.
    843 #define DoCall(boxed_type, shorty, c_type, bad_value)                   \
    844   {                                                                     \
    845     jclass prim_class = env_->FindClass("java/lang/" #boxed_type);      \
    846     jmethodID method = env_->GetStaticMethodID(prim_class, "valueOf",   \
    847                                                "(" #shorty ")Ljava/lang/" #boxed_type ";"); \
    848     EXPECT_NE(nullptr, method);                                         \
    849     EXPECT_FALSE(env_->ExceptionCheck());                               \
    850     CheckJniAbortCatcher check_jni_abort_catcher;                       \
    851     env_->CallStaticObjectMethod(prim_class, method, bad_value);        \
    852     check_jni_abort_catcher.Check("unexpected " #c_type " value: " #bad_value); \
    853   }
    854 
    855   DoCall(Boolean, Z, jboolean, 2);
    856   DoCall(Byte, B, jbyte, 128);
    857   DoCall(Byte, B, jbyte, -129);
    858   DoCall(Short, S, jshort, 32768);
    859   DoCall(Short, S, jshort, -32769);
    860   DoCall(Character, C, jchar, 65536);
    861   DoCall(Character, C, jchar, -1);
    862 #undef DoCall
    863 }
    864 
    865 TEST_F(JniInternalTest, CallJValueMethodBadPrimitive) {
    866   // Check that bad primitive values, passed as jvalues, cause check
    867   // JNI to abort. Unlike with var args, sizes less than an int should
    868   // be truncated or sign extended and not cause an abort except for
    869   // jbooleans that are passed as bytes.
    870 #define DoFailCall(boxed_type, shorty, c_type, bad_value)               \
    871   {                                                                     \
    872     jclass prim_class = env_->FindClass("java/lang/" #boxed_type);      \
    873     jmethodID method = env_->GetStaticMethodID(prim_class, "valueOf",   \
    874                                                "(" #shorty ")Ljava/lang/" #boxed_type ";"); \
    875     EXPECT_NE(nullptr, method);                                         \
    876     EXPECT_FALSE(env_->ExceptionCheck());                               \
    877     CheckJniAbortCatcher check_jni_abort_catcher;                       \
    878     jvalue jval;                                                        \
    879     jval.i = bad_value;                                                 \
    880     env_->CallStaticObjectMethodA(prim_class, method, &jval);           \
    881     check_jni_abort_catcher.Check("unexpected " #c_type " value: " #bad_value); \
    882   }
    883 #define DoGoodCall(boxed_type, shorty, c_type, bad_value)               \
    884   {                                                                     \
    885     jclass prim_class = env_->FindClass("java/lang/" #boxed_type);      \
    886     jmethodID method = env_->GetStaticMethodID(prim_class, "valueOf",   \
    887                                                "(" #shorty ")Ljava/lang/" #boxed_type ";"); \
    888     EXPECT_NE(nullptr, method);                                         \
    889     EXPECT_FALSE(env_->ExceptionCheck());                               \
    890     jvalue jval;                                                        \
    891     jval.i = bad_value;                                                 \
    892     env_->CallStaticObjectMethodA(prim_class, method, &jval);           \
    893   }
    894 
    895   DoFailCall(Boolean, Z, jboolean, 2);
    896   DoGoodCall(Byte, B, jbyte, 128);
    897   DoGoodCall(Byte, B, jbyte, -129);
    898   DoGoodCall(Short, S, jshort, 32768);
    899   DoGoodCall(Short, S, jshort, -32769);
    900   DoGoodCall(Character, C, jchar, 65536);
    901   DoGoodCall(Character, C, jchar, -1);
    902 #undef DoCall
    903 }
    904 
    905 TEST_F(JniInternalTest, GetStaticMethodID) {
    906   jclass jlobject = env_->FindClass("java/lang/Object");
    907   jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
    908 
    909   // Sanity check that no exceptions are pending
    910   ASSERT_FALSE(env_->ExceptionCheck());
    911 
    912   // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
    913   // a pending exception
    914   jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V");
    915   EXPECT_EQ(nullptr, method);
    916   ExpectException(jlnsme);
    917 
    918   // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as
    919   // the method is not static
    920   method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
    921   EXPECT_EQ(nullptr, method);
    922   ExpectException(jlnsme);
    923 
    924   // Check that java.lang.String.valueOf(int) does exist
    925   jclass jlstring = env_->FindClass("java/lang/String");
    926   method = env_->GetStaticMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
    927   EXPECT_NE(nullptr, method);
    928   EXPECT_FALSE(env_->ExceptionCheck());
    929 
    930   // Bad arguments.
    931   GetStaticMethodIdBadArgumentTest(false);
    932   GetStaticMethodIdBadArgumentTest(true);
    933 }
    934 
    935 static size_t GetLocalsCapacity(JNIEnv* env) {
    936   ScopedObjectAccess soa(Thread::Current());
    937   return reinterpret_cast<JNIEnvExt*>(env)->GetLocalsCapacity();
    938 }
    939 
    940 TEST_F(JniInternalTest, FromReflectedField_ToReflectedField) {
    941   jclass jlrField = env_->FindClass("java/lang/reflect/Field");
    942   jclass c = env_->FindClass("java/lang/String");
    943   ASSERT_NE(c, nullptr);
    944   jfieldID fid = env_->GetFieldID(c, "count", "I");
    945   ASSERT_NE(fid, nullptr);
    946   // Turn the fid into a java.lang.reflect.Field...
    947   jobject field = env_->ToReflectedField(c, fid, JNI_FALSE);
    948   size_t capacity_before = GetLocalsCapacity(env_);
    949   for (size_t i = 0; i <= 10; ++i) {
    950     // Regression test for b/18396311, ToReflectedField leaking local refs causing a local
    951     // reference table overflows with 512 references to ArtField
    952     env_->DeleteLocalRef(env_->ToReflectedField(c, fid, JNI_FALSE));
    953   }
    954   size_t capacity_after = GetLocalsCapacity(env_);
    955   ASSERT_EQ(capacity_before, capacity_after);
    956 
    957   ASSERT_NE(c, nullptr);
    958   ASSERT_TRUE(env_->IsInstanceOf(field, jlrField));
    959   // ...and back again.
    960   jfieldID fid2 = env_->FromReflectedField(field);
    961   ASSERT_NE(fid2, nullptr);
    962   // Make sure we can actually use it.
    963   jstring s = env_->NewStringUTF("poop");
    964   if (mirror::kUseStringCompression) {
    965     ASSERT_EQ(mirror::String::GetFlaggedCount(4, /* compressible */ true),
    966               env_->GetIntField(s, fid2));
    967     // Create incompressible string
    968     jstring s_16 = env_->NewStringUTF("\u0444\u0444");
    969     ASSERT_EQ(mirror::String::GetFlaggedCount(2, /* compressible */ false),
    970               env_->GetIntField(s_16, fid2));
    971   } else {
    972     ASSERT_EQ(4, env_->GetIntField(s, fid2));
    973   }
    974   // Bad arguments.
    975   GetFromReflectedField_ToReflectedFieldBadArgumentTest(false);
    976   GetFromReflectedField_ToReflectedFieldBadArgumentTest(true);
    977 }
    978 
    979 TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
    980   jclass jlrMethod = env_->FindClass("java/lang/reflect/Method");
    981   ASSERT_NE(jlrMethod, nullptr);
    982   jclass jlrConstructor = env_->FindClass("java/lang/reflect/Constructor");
    983   ASSERT_NE(jlrConstructor, nullptr);
    984   jclass c = env_->FindClass("java/lang/String");
    985   ASSERT_NE(c, nullptr);
    986 
    987   jmethodID mid = env_->GetMethodID(c, "<init>", "()V");
    988   ASSERT_NE(mid, nullptr);
    989   // Turn the mid into a java.lang.reflect.Constructor...
    990   jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
    991   size_t capacity_before = GetLocalsCapacity(env_);
    992   for (size_t i = 0; i <= 10; ++i) {
    993     // Regression test for b/18396311, ToReflectedMethod leaking local refs causing a local
    994     // reference table overflows with 512 references to ArtMethod
    995     env_->DeleteLocalRef(env_->ToReflectedMethod(c, mid, JNI_FALSE));
    996   }
    997   size_t capacity_after = GetLocalsCapacity(env_);
    998   ASSERT_EQ(capacity_before, capacity_after);
    999   ASSERT_NE(method, nullptr);
   1000   ASSERT_TRUE(env_->IsInstanceOf(method, jlrConstructor));
   1001   // ...and back again.
   1002   jmethodID mid2 = env_->FromReflectedMethod(method);
   1003   ASSERT_NE(mid2, nullptr);
   1004   // Make sure we can actually use it.
   1005   jstring s = reinterpret_cast<jstring>(env_->AllocObject(c));
   1006   ASSERT_NE(s, nullptr);
   1007   env_->CallVoidMethod(s, mid2);
   1008   ASSERT_EQ(JNI_FALSE, env_->ExceptionCheck());
   1009   env_->ExceptionClear();
   1010 
   1011   mid = env_->GetMethodID(c, "length", "()I");
   1012   ASSERT_NE(mid, nullptr);
   1013   // Turn the mid into a java.lang.reflect.Method...
   1014   method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
   1015   ASSERT_NE(method, nullptr);
   1016   ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod));
   1017   // ...and back again.
   1018   mid2 = env_->FromReflectedMethod(method);
   1019   ASSERT_NE(mid2, nullptr);
   1020   // Make sure we can actually use it.
   1021   s = env_->NewStringUTF("poop");
   1022   ASSERT_NE(s, nullptr);
   1023   ASSERT_EQ(4, env_->CallIntMethod(s, mid2));
   1024 
   1025   // Bad arguments.
   1026   GetFromReflectedMethod_ToReflectedMethodBadArgumentTest(false);
   1027   GetFromReflectedMethod_ToReflectedMethodBadArgumentTest(true);
   1028 }
   1029 
   1030 static void BogusMethod() {
   1031   // You can't pass null function pointers to RegisterNatives.
   1032 }
   1033 
   1034 TEST_F(JniInternalTest, RegisterAndUnregisterNatives) {
   1035   jclass jlobject = env_->FindClass("java/lang/Object");
   1036   jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
   1037   void* native_function = reinterpret_cast<void*>(BogusMethod);
   1038 
   1039   // Sanity check that no exceptions are pending.
   1040   ASSERT_FALSE(env_->ExceptionCheck());
   1041 
   1042   // The following can print errors to the log we'd like to ignore.
   1043   {
   1044     ScopedLogSeverity sls(LogSeverity::FATAL);
   1045     // Check that registering method without name causes a NoSuchMethodError.
   1046     {
   1047       JNINativeMethod methods[] = { { nullptr, "()V", native_function } };
   1048       EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
   1049     }
   1050     ExpectException(jlnsme);
   1051 
   1052     // Check that registering method without signature causes a NoSuchMethodError.
   1053     {
   1054       JNINativeMethod methods[] = { { "notify", nullptr, native_function } };
   1055       EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
   1056     }
   1057     ExpectException(jlnsme);
   1058 
   1059     // Check that registering method without function causes a NoSuchMethodError.
   1060     {
   1061       JNINativeMethod methods[] = { { "notify", "()V", nullptr } };
   1062       EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
   1063     }
   1064     ExpectException(jlnsme);
   1065 
   1066     // Check that registering to a non-existent java.lang.Object.foo() causes a NoSuchMethodError.
   1067     {
   1068       JNINativeMethod methods[] = { { "foo", "()V", native_function } };
   1069       EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
   1070     }
   1071     ExpectException(jlnsme);
   1072 
   1073     // Check that registering non-native methods causes a NoSuchMethodError.
   1074     {
   1075       JNINativeMethod methods[] = { { "equals", "(Ljava/lang/Object;)Z", native_function } };
   1076       EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
   1077     }
   1078     ExpectException(jlnsme);
   1079   }
   1080 
   1081   // Check that registering native methods is successful.
   1082   {
   1083     JNINativeMethod methods[] = { { "notify", "()V", native_function } };
   1084     EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_OK);
   1085   }
   1086   EXPECT_FALSE(env_->ExceptionCheck());
   1087   EXPECT_EQ(env_->UnregisterNatives(jlobject), JNI_OK);
   1088 
   1089   // Check that registering no methods isn't a failure.
   1090   {
   1091     JNINativeMethod methods[] = { };
   1092     EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 0), JNI_OK);
   1093   }
   1094   EXPECT_FALSE(env_->ExceptionCheck());
   1095   EXPECT_EQ(env_->UnregisterNatives(jlobject), JNI_OK);
   1096 
   1097   // Check that registering a -ve number of methods is a failure.
   1098   CheckJniAbortCatcher check_jni_abort_catcher;
   1099   for (int i = -10; i < 0; ++i) {
   1100     JNINativeMethod methods[] = { };
   1101     EXPECT_EQ(env_->RegisterNatives(jlobject, methods, i), JNI_ERR);
   1102     check_jni_abort_catcher.Check("negative method count: ");
   1103   }
   1104   EXPECT_FALSE(env_->ExceptionCheck());
   1105 
   1106   // Unregistering a class with no natives is a warning.
   1107   EXPECT_EQ(env_->UnregisterNatives(jlnsme), JNI_OK);
   1108 
   1109   RegisterAndUnregisterNativesBadArguments(false, &check_jni_abort_catcher);
   1110   RegisterAndUnregisterNativesBadArguments(true, &check_jni_abort_catcher);
   1111 }
   1112 
   1113 #define EXPECT_PRIMITIVE_ARRAY(new_fn, \
   1114                                get_region_fn, \
   1115                                set_region_fn, \
   1116                                get_elements_fn, \
   1117                                release_elements_fn, \
   1118                                scalar_type, \
   1119                                expected_class_descriptor) \
   1120   jsize size = 4; \
   1121   \
   1122   { \
   1123     CheckJniAbortCatcher jni_abort_catcher; \
   1124     down_cast<JNIEnvExt*>(env_)->SetCheckJniEnabled(false); \
   1125     /* Allocate an negative sized array and check it has the right failure type. */ \
   1126     EXPECT_EQ(env_->new_fn(-1), nullptr); \
   1127     jni_abort_catcher.Check("negative array length: -1"); \
   1128     EXPECT_EQ(env_->new_fn(std::numeric_limits<jint>::min()), nullptr); \
   1129     jni_abort_catcher.Check("negative array length: -2147483648"); \
   1130     /* Pass the array as null. */ \
   1131     EXPECT_EQ(0, env_->GetArrayLength(nullptr)); \
   1132     jni_abort_catcher.Check("java_array == null"); \
   1133     env_->get_region_fn(nullptr, 0, 0, nullptr); \
   1134     jni_abort_catcher.Check("java_array == null"); \
   1135     env_->set_region_fn(nullptr, 0, 0, nullptr); \
   1136     jni_abort_catcher.Check("java_array == null"); \
   1137     env_->get_elements_fn(nullptr, nullptr); \
   1138     jni_abort_catcher.Check("java_array == null"); \
   1139     env_->release_elements_fn(nullptr, nullptr, 0); \
   1140     jni_abort_catcher.Check("java_array == null"); \
   1141     /* Pass the elements for region as null. */ \
   1142     scalar_type ## Array a = env_->new_fn(size); \
   1143     env_->get_region_fn(a, 0, size, nullptr); \
   1144     jni_abort_catcher.Check("buf == null"); \
   1145     env_->set_region_fn(a, 0, size, nullptr); \
   1146     jni_abort_catcher.Check("buf == null"); \
   1147     down_cast<JNIEnvExt*>(env_)->SetCheckJniEnabled(true); \
   1148   } \
   1149   /* Allocate an array and check it has the right type and length. */ \
   1150   scalar_type ## Array a = env_->new_fn(size); \
   1151   EXPECT_NE(a, nullptr); \
   1152   EXPECT_TRUE(env_->IsInstanceOf(a, env_->FindClass(expected_class_descriptor))); \
   1153   EXPECT_EQ(size, env_->GetArrayLength(a)); \
   1154   \
   1155   /* GetPrimitiveArrayRegion/SetPrimitiveArrayRegion */ \
   1156   /* AIOOBE for negative start offset. */ \
   1157   env_->get_region_fn(a, -1, 1, nullptr); \
   1158   ExpectException(aioobe_); \
   1159   env_->set_region_fn(a, -1, 1, nullptr); \
   1160   ExpectException(aioobe_); \
   1161   \
   1162   /* AIOOBE for negative length. */ \
   1163   env_->get_region_fn(a, 0, -1, nullptr); \
   1164   ExpectException(aioobe_); \
   1165   env_->set_region_fn(a, 0, -1, nullptr); \
   1166   ExpectException(aioobe_); \
   1167   \
   1168   /* AIOOBE for buffer overrun. */ \
   1169   env_->get_region_fn(a, size - 1, size, nullptr); \
   1170   ExpectException(aioobe_); \
   1171   env_->set_region_fn(a, size - 1, size, nullptr); \
   1172   ExpectException(aioobe_); \
   1173   \
   1174   /* Regression test against integer overflow in range check. */ \
   1175   env_->get_region_fn(a, 0x7fffffff, 0x7fffffff, nullptr); \
   1176   ExpectException(aioobe_); \
   1177   env_->set_region_fn(a, 0x7fffffff, 0x7fffffff, nullptr); \
   1178   ExpectException(aioobe_); \
   1179   \
   1180   /* It's okay for the buffer to be null as long as the length is 0. */ \
   1181   env_->get_region_fn(a, 2, 0, nullptr); \
   1182   /* Even if the offset is invalid... */ \
   1183   env_->get_region_fn(a, 123, 0, nullptr); \
   1184   ExpectException(aioobe_); \
   1185   \
   1186   /* It's okay for the buffer to be null as long as the length is 0. */ \
   1187   env_->set_region_fn(a, 2, 0, nullptr); \
   1188   /* Even if the offset is invalid... */ \
   1189   env_->set_region_fn(a, 123, 0, nullptr); \
   1190   ExpectException(aioobe_); \
   1191   \
   1192   /* Prepare a couple of buffers. */ \
   1193   /* NOLINT, no parentheses around scalar_type. */ \
   1194   std::unique_ptr<scalar_type[]> src_buf(new scalar_type[size]); /* NOLINT */ \
   1195   std::unique_ptr<scalar_type[]> dst_buf(new scalar_type[size]); /* NOLINT */ \
   1196   for (jsize i = 0; i < size; ++i) { src_buf[i] = scalar_type(i); } \
   1197   for (jsize i = 0; i < size; ++i) { dst_buf[i] = scalar_type(-1); } \
   1198   \
   1199   /* Copy all of src_buf onto the heap. */ \
   1200   env_->set_region_fn(a, 0, size, &src_buf[0]); \
   1201   /* Copy back only part. */ \
   1202   env_->get_region_fn(a, 1, size - 2, &dst_buf[1]); \
   1203   EXPECT_NE(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
   1204     << "short copy equal"; \
   1205   /* Copy the missing pieces. */ \
   1206   env_->get_region_fn(a, 0, 1, &dst_buf[0]); \
   1207   env_->get_region_fn(a, size - 1, 1, &dst_buf[size - 1]); \
   1208   EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
   1209     << "fixed copy not equal"; \
   1210   /* Copy back the whole array. */ \
   1211   env_->get_region_fn(a, 0, size, &dst_buf[0]); \
   1212   EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
   1213     << "full copy not equal"; \
   1214   /* GetPrimitiveArrayCritical */ \
   1215   void* v = env_->GetPrimitiveArrayCritical(a, nullptr); \
   1216   EXPECT_EQ(memcmp(&src_buf[0], v, size * sizeof(scalar_type)), 0) \
   1217     << "GetPrimitiveArrayCritical not equal"; \
   1218   env_->ReleasePrimitiveArrayCritical(a, v, 0); \
   1219   /* GetXArrayElements */ \
   1220   scalar_type* xs = env_->get_elements_fn(a, nullptr); /* NOLINT, scalar_type */ \
   1221   EXPECT_EQ(memcmp(&src_buf[0], xs, size * sizeof(scalar_type)), 0) \
   1222     << # get_elements_fn " not equal"; \
   1223   env_->release_elements_fn(a, xs, 0); \
   1224 
   1225 TEST_F(JniInternalTest, BooleanArrays) {
   1226   EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion,
   1227                          GetBooleanArrayElements, ReleaseBooleanArrayElements, jboolean, "[Z");
   1228 }
   1229 TEST_F(JniInternalTest, ByteArrays) {
   1230   EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion,
   1231                          GetByteArrayElements, ReleaseByteArrayElements, jbyte, "[B");
   1232 }
   1233 TEST_F(JniInternalTest, CharArrays) {
   1234   EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion,
   1235                          GetCharArrayElements, ReleaseCharArrayElements, jchar, "[C");
   1236 }
   1237 TEST_F(JniInternalTest, DoubleArrays) {
   1238   EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion,
   1239                          GetDoubleArrayElements, ReleaseDoubleArrayElements, jdouble, "[D");
   1240 }
   1241 TEST_F(JniInternalTest, FloatArrays) {
   1242   EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion,
   1243                          GetFloatArrayElements, ReleaseFloatArrayElements, jfloat, "[F");
   1244 }
   1245 TEST_F(JniInternalTest, IntArrays) {
   1246   EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion,
   1247                          GetIntArrayElements, ReleaseIntArrayElements, jint, "[I");
   1248 }
   1249 TEST_F(JniInternalTest, LongArrays) {
   1250   EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion,
   1251                          GetLongArrayElements, ReleaseLongArrayElements, jlong, "[J");
   1252 }
   1253 TEST_F(JniInternalTest, ShortArrays) {
   1254   EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion,
   1255                          GetShortArrayElements, ReleaseShortArrayElements, jshort, "[S");
   1256 }
   1257 
   1258 TEST_F(JniInternalTest, GetPrimitiveArrayElementsOfWrongType) {
   1259   GetPrimitiveArrayElementsOfWrongType(false);
   1260   GetPrimitiveArrayElementsOfWrongType(true);
   1261 }
   1262 
   1263 TEST_F(JniInternalTest, ReleasePrimitiveArrayElementsOfWrongType) {
   1264   ReleasePrimitiveArrayElementsOfWrongType(false);
   1265   ReleasePrimitiveArrayElementsOfWrongType(true);
   1266 }
   1267 
   1268 TEST_F(JniInternalTest, GetReleasePrimitiveArrayCriticalOfWrongType) {
   1269   GetReleasePrimitiveArrayCriticalOfWrongType(false);
   1270   GetReleasePrimitiveArrayCriticalOfWrongType(true);
   1271 }
   1272 
   1273 TEST_F(JniInternalTest, GetPrimitiveArrayRegionElementsOfWrongType) {
   1274   GetPrimitiveArrayRegionElementsOfWrongType(false);
   1275   GetPrimitiveArrayRegionElementsOfWrongType(true);
   1276 }
   1277 
   1278 TEST_F(JniInternalTest, SetPrimitiveArrayRegionElementsOfWrongType) {
   1279   SetPrimitiveArrayRegionElementsOfWrongType(false);
   1280   SetPrimitiveArrayRegionElementsOfWrongType(true);
   1281 }
   1282 
   1283 TEST_F(JniInternalTest, NewObjectArray) {
   1284   jclass element_class = env_->FindClass("java/lang/String");
   1285   ASSERT_NE(element_class, nullptr);
   1286   jclass array_class = env_->FindClass("[Ljava/lang/String;");
   1287   ASSERT_NE(array_class, nullptr);
   1288 
   1289   jobjectArray a = env_->NewObjectArray(0, element_class, nullptr);
   1290   EXPECT_NE(a, nullptr);
   1291   EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
   1292   EXPECT_EQ(0, env_->GetArrayLength(a));
   1293 
   1294   a = env_->NewObjectArray(1, element_class, nullptr);
   1295   EXPECT_NE(a, nullptr);
   1296   EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
   1297   EXPECT_EQ(1, env_->GetArrayLength(a));
   1298   EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), nullptr));
   1299 
   1300   // Negative array length checks.
   1301   NewObjectArrayBadArguments(false);
   1302   NewObjectArrayBadArguments(true);
   1303 }
   1304 
   1305 TEST_F(JniInternalTest, NewObjectArrayWithPrimitiveClasses) {
   1306   const char* primitive_descriptors = "VZBSCIJFD";
   1307   const char* primitive_names[] = {
   1308       "void", "boolean", "byte", "short", "char", "int", "long", "float", "double"
   1309   };
   1310   ASSERT_EQ(strlen(primitive_descriptors), arraysize(primitive_names));
   1311 
   1312   bool old_check_jni = vm_->SetCheckJniEnabled(false);
   1313   CheckJniAbortCatcher jni_abort_catcher;
   1314   for (size_t i = 0; i < strlen(primitive_descriptors); ++i) {
   1315     env_->NewObjectArray(0, nullptr, nullptr);
   1316     jni_abort_catcher.Check("element_jclass == null");
   1317     jclass primitive_class = GetPrimitiveClass(primitive_descriptors[i]);
   1318     env_->NewObjectArray(1, primitive_class, nullptr);
   1319     std::string error_msg(StringPrintf("not an object type: %s", primitive_names[i]));
   1320     jni_abort_catcher.Check(error_msg.c_str());
   1321   }
   1322   EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
   1323   for (size_t i = 0; i < strlen(primitive_descriptors); ++i) {
   1324     env_->NewObjectArray(0, nullptr, nullptr);
   1325     jni_abort_catcher.Check("NewObjectArray received NULL jclass");
   1326     jclass primitive_class = GetPrimitiveClass(primitive_descriptors[i]);
   1327     env_->NewObjectArray(1, primitive_class, nullptr);
   1328     std::string error_msg(StringPrintf("not an object type: %s", primitive_names[i]));
   1329     jni_abort_catcher.Check(error_msg.c_str());
   1330   }
   1331   EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
   1332 }
   1333 
   1334 TEST_F(JniInternalTest, NewObjectArrayWithInitialValue) {
   1335   jclass element_class = env_->FindClass("java/lang/String");
   1336   ASSERT_NE(element_class, nullptr);
   1337   jclass array_class = env_->FindClass("[Ljava/lang/String;");
   1338   ASSERT_NE(array_class, nullptr);
   1339 
   1340   jstring s = env_->NewStringUTF("poop");
   1341   jobjectArray a = env_->NewObjectArray(2, element_class, s);
   1342   EXPECT_NE(a, nullptr);
   1343   EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
   1344   EXPECT_EQ(2, env_->GetArrayLength(a));
   1345   EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), s));
   1346   EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 1), s));
   1347 
   1348   // Attempt to incorrect create an array of strings with initial value of string arrays.
   1349   CheckJniAbortCatcher jni_abort_catcher;
   1350   env_->NewObjectArray(2, element_class, a);
   1351   jni_abort_catcher.Check("cannot assign object of type 'java.lang.String[]' to array with element "
   1352                           "type of 'java.lang.String'");
   1353 }
   1354 
   1355 TEST_F(JniInternalTest, GetArrayLength) {
   1356   // Already tested in NewObjectArray/NewPrimitiveArray except for null.
   1357   CheckJniAbortCatcher jni_abort_catcher;
   1358   bool old_check_jni = vm_->SetCheckJniEnabled(false);
   1359   EXPECT_EQ(0, env_->GetArrayLength(nullptr));
   1360   jni_abort_catcher.Check("java_array == null");
   1361   EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
   1362   EXPECT_EQ(JNI_ERR, env_->GetArrayLength(nullptr));
   1363   jni_abort_catcher.Check("jarray was NULL");
   1364   EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
   1365 }
   1366 
   1367 TEST_F(JniInternalTest, GetObjectClass) {
   1368   jclass string_class = env_->FindClass("java/lang/String");
   1369   ASSERT_NE(string_class, nullptr);
   1370   jclass class_class = env_->FindClass("java/lang/Class");
   1371   ASSERT_NE(class_class, nullptr);
   1372 
   1373   jstring s = env_->NewStringUTF("poop");
   1374   jclass c = env_->GetObjectClass(s);
   1375   ASSERT_TRUE(env_->IsSameObject(string_class, c));
   1376 
   1377   jclass c2 = env_->GetObjectClass(c);
   1378   ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2)));
   1379 
   1380   // Null as object should fail.
   1381   CheckJniAbortCatcher jni_abort_catcher;
   1382   EXPECT_EQ(env_->GetObjectClass(nullptr), nullptr);
   1383   jni_abort_catcher.Check("java_object == null");
   1384 }
   1385 
   1386 TEST_F(JniInternalTest, GetSuperclass) {
   1387   jclass object_class = env_->FindClass("java/lang/Object");
   1388   ASSERT_NE(object_class, nullptr);
   1389   jclass string_class = env_->FindClass("java/lang/String");
   1390   ASSERT_NE(string_class, nullptr);
   1391   jclass runnable_interface = env_->FindClass("java/lang/Runnable");
   1392   ASSERT_NE(runnable_interface, nullptr);
   1393   ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class)));
   1394   ASSERT_EQ(env_->GetSuperclass(object_class), nullptr);
   1395   ASSERT_EQ(env_->GetSuperclass(runnable_interface), nullptr);
   1396 
   1397   // Null as class should fail.
   1398   CheckJniAbortCatcher jni_abort_catcher;
   1399   bool old_check_jni = vm_->SetCheckJniEnabled(false);
   1400   EXPECT_EQ(env_->GetSuperclass(nullptr), nullptr);
   1401   jni_abort_catcher.Check("java_class == null");
   1402   EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
   1403   EXPECT_EQ(env_->GetSuperclass(nullptr), nullptr);
   1404   jni_abort_catcher.Check("GetSuperclass received NULL jclass");
   1405   EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
   1406 }
   1407 
   1408 TEST_F(JniInternalTest, IsAssignableFrom) {
   1409   jclass object_class = env_->FindClass("java/lang/Object");
   1410   ASSERT_NE(object_class, nullptr);
   1411   jclass string_class = env_->FindClass("java/lang/String");
   1412   ASSERT_NE(string_class, nullptr);
   1413 
   1414   // A superclass is assignable from an instance of its
   1415   // subclass but not vice versa.
   1416   ASSERT_TRUE(env_->IsAssignableFrom(string_class, object_class));
   1417   ASSERT_FALSE(env_->IsAssignableFrom(object_class, string_class));
   1418 
   1419   jclass charsequence_interface = env_->FindClass("java/lang/CharSequence");
   1420   ASSERT_NE(charsequence_interface, nullptr);
   1421 
   1422   // An interface is assignable from an instance of an implementing
   1423   // class but not vice versa.
   1424   ASSERT_TRUE(env_->IsAssignableFrom(string_class, charsequence_interface));
   1425   ASSERT_FALSE(env_->IsAssignableFrom(charsequence_interface, string_class));
   1426 
   1427   // Check that arrays are covariant.
   1428   jclass string_array_class = env_->FindClass("[Ljava/lang/String;");
   1429   ASSERT_NE(string_array_class, nullptr);
   1430   jclass object_array_class = env_->FindClass("[Ljava/lang/Object;");
   1431   ASSERT_NE(object_array_class, nullptr);
   1432   ASSERT_TRUE(env_->IsAssignableFrom(string_array_class, object_array_class));
   1433   ASSERT_FALSE(env_->IsAssignableFrom(object_array_class, string_array_class));
   1434 
   1435   // Primitive types are tested in 004-JniTest.
   1436 
   1437   // Null as either class should fail.
   1438   CheckJniAbortCatcher jni_abort_catcher;
   1439   bool old_check_jni = vm_->SetCheckJniEnabled(false);
   1440   EXPECT_EQ(env_->IsAssignableFrom(nullptr, string_class), JNI_FALSE);
   1441   jni_abort_catcher.Check("java_class1 == null");
   1442   EXPECT_EQ(env_->IsAssignableFrom(object_class, nullptr), JNI_FALSE);
   1443   jni_abort_catcher.Check("java_class2 == null");
   1444   EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
   1445   EXPECT_EQ(env_->IsAssignableFrom(nullptr, string_class), JNI_FALSE);
   1446   jni_abort_catcher.Check("IsAssignableFrom received NULL jclass");
   1447   EXPECT_EQ(env_->IsAssignableFrom(object_class, nullptr), JNI_FALSE);
   1448   jni_abort_catcher.Check("IsAssignableFrom received NULL jclass");
   1449   EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
   1450 }
   1451 
   1452 TEST_F(JniInternalTest, GetObjectRefType) {
   1453   jclass local = env_->FindClass("java/lang/Object");
   1454   ASSERT_TRUE(local != nullptr);
   1455   EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(local));
   1456 
   1457   jobject global = env_->NewGlobalRef(local);
   1458   EXPECT_EQ(JNIGlobalRefType, env_->GetObjectRefType(global));
   1459 
   1460   jweak weak_global = env_->NewWeakGlobalRef(local);
   1461   EXPECT_EQ(JNIWeakGlobalRefType, env_->GetObjectRefType(weak_global));
   1462 
   1463   {
   1464     CheckJniAbortCatcher jni_abort_catcher;
   1465     jobject invalid = reinterpret_cast<jobject>(this);
   1466     EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(invalid));
   1467     jni_abort_catcher.Check("use of invalid jobject");
   1468   }
   1469 
   1470   // TODO: invoke a native method and test that its arguments are considered local references.
   1471 
   1472   // Null as pointer should not fail and return invalid-ref. b/18820997
   1473   EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(nullptr));
   1474 
   1475   // TODO: Null as reference should return the original type.
   1476   // This requires running a GC so a non-null object gets freed.
   1477 }
   1478 
   1479 TEST_F(JniInternalTest, StaleWeakGlobal) {
   1480   jclass java_lang_Class = env_->FindClass("java/lang/Class");
   1481   ASSERT_NE(java_lang_Class, nullptr);
   1482   jobjectArray local_ref = env_->NewObjectArray(1, java_lang_Class, nullptr);
   1483   ASSERT_NE(local_ref, nullptr);
   1484   jweak weak_global = env_->NewWeakGlobalRef(local_ref);
   1485   ASSERT_NE(weak_global, nullptr);
   1486   env_->DeleteLocalRef(local_ref);
   1487   // GC should clear the weak global.
   1488   Runtime::Current()->GetHeap()->CollectGarbage(/* clear_soft_references */ false);
   1489   jobject new_global_ref = env_->NewGlobalRef(weak_global);
   1490   EXPECT_EQ(new_global_ref, nullptr);
   1491   jobject new_local_ref = env_->NewLocalRef(weak_global);
   1492   EXPECT_EQ(new_local_ref, nullptr);
   1493 }
   1494 
   1495 TEST_F(JniInternalTest, NewStringUTF) {
   1496   EXPECT_EQ(env_->NewStringUTF(nullptr), nullptr);
   1497   jstring s;
   1498 
   1499   s = env_->NewStringUTF("");
   1500   EXPECT_NE(s, nullptr);
   1501   EXPECT_EQ(0, env_->GetStringLength(s));
   1502   EXPECT_EQ(0, env_->GetStringUTFLength(s));
   1503   s = env_->NewStringUTF("hello");
   1504   EXPECT_NE(s, nullptr);
   1505   EXPECT_EQ(5, env_->GetStringLength(s));
   1506   EXPECT_EQ(5, env_->GetStringUTFLength(s));
   1507 
   1508   // Encoded surrogate pair.
   1509   s = env_->NewStringUTF("\xed\xa0\x81\xed\xb0\x80");
   1510   EXPECT_NE(s, nullptr);
   1511   EXPECT_EQ(2, env_->GetStringLength(s));
   1512 
   1513   // The surrogate pair gets encoded into a 4 byte UTF sequence..
   1514   EXPECT_EQ(4, env_->GetStringUTFLength(s));
   1515   const char* chars = env_->GetStringUTFChars(s, nullptr);
   1516   EXPECT_STREQ("\xf0\x90\x90\x80", chars);
   1517   env_->ReleaseStringUTFChars(s, chars);
   1518 
   1519   // .. but is stored as is in the utf-16 representation.
   1520   const jchar* jchars = env_->GetStringChars(s, nullptr);
   1521   EXPECT_EQ(0xd801, jchars[0]);
   1522   EXPECT_EQ(0xdc00, jchars[1]);
   1523   env_->ReleaseStringChars(s, jchars);
   1524 
   1525   // 4 byte UTF sequence appended to an encoded surrogate pair.
   1526   s = env_->NewStringUTF("\xed\xa0\x81\xed\xb0\x80 \xf0\x9f\x8f\xa0");
   1527   EXPECT_NE(s, nullptr);
   1528 
   1529   // The 4 byte sequence {0xf0, 0x9f, 0x8f, 0xa0} is converted into a surrogate
   1530   // pair {0xd83c, 0xdfe0}.
   1531   EXPECT_EQ(5, env_->GetStringLength(s));
   1532   jchars = env_->GetStringChars(s, nullptr);
   1533   // The first surrogate pair, encoded as such in the input.
   1534   EXPECT_EQ(0xd801, jchars[0]);
   1535   EXPECT_EQ(0xdc00, jchars[1]);
   1536   // The second surrogate pair, from the 4 byte UTF sequence in the input.
   1537   EXPECT_EQ(0xd83c, jchars[3]);
   1538   EXPECT_EQ(0xdfe0, jchars[4]);
   1539   env_->ReleaseStringChars(s, jchars);
   1540 
   1541   EXPECT_EQ(9, env_->GetStringUTFLength(s));
   1542   chars = env_->GetStringUTFChars(s, nullptr);
   1543   EXPECT_STREQ("\xf0\x90\x90\x80 \xf0\x9f\x8f\xa0", chars);
   1544   env_->ReleaseStringUTFChars(s, chars);
   1545 
   1546   // A string with 1, 2, 3 and 4 byte UTF sequences with spaces
   1547   // between them
   1548   s = env_->NewStringUTF("\x24 \xc2\xa2 \xe2\x82\xac \xf0\x9f\x8f\xa0");
   1549   EXPECT_NE(s, nullptr);
   1550   EXPECT_EQ(8, env_->GetStringLength(s));
   1551   EXPECT_EQ(13, env_->GetStringUTFLength(s));
   1552 }
   1553 
   1554 TEST_F(JniInternalTest, NewString) {
   1555   jchar chars[] = { 'h', 'i' };
   1556   jstring s;
   1557   s = env_->NewString(chars, 0);
   1558   EXPECT_NE(s, nullptr);
   1559   EXPECT_EQ(0, env_->GetStringLength(s));
   1560   EXPECT_EQ(0, env_->GetStringUTFLength(s));
   1561   s = env_->NewString(chars, 2);
   1562   EXPECT_NE(s, nullptr);
   1563   EXPECT_EQ(2, env_->GetStringLength(s));
   1564   EXPECT_EQ(2, env_->GetStringUTFLength(s));
   1565 
   1566   // TODO: check some non-ASCII strings.
   1567 }
   1568 
   1569 TEST_F(JniInternalTest, NewStringNullCharsZeroLength) {
   1570   jstring s = env_->NewString(nullptr, 0);
   1571   EXPECT_NE(s, nullptr);
   1572   EXPECT_EQ(0, env_->GetStringLength(s));
   1573 }
   1574 
   1575 TEST_F(JniInternalTest, NewStringNullCharsNonzeroLength) {
   1576   CheckJniAbortCatcher jni_abort_catcher;
   1577   env_->NewString(nullptr, 1);
   1578   jni_abort_catcher.Check("chars == null && char_count > 0");
   1579 }
   1580 
   1581 TEST_F(JniInternalTest, NewStringNegativeLength) {
   1582   CheckJniAbortCatcher jni_abort_catcher;
   1583   bool old_check_jni = vm_->SetCheckJniEnabled(false);
   1584   env_->NewString(nullptr, -1);
   1585   jni_abort_catcher.Check("char_count < 0: -1");
   1586   env_->NewString(nullptr, std::numeric_limits<jint>::min());
   1587   jni_abort_catcher.Check("char_count < 0: -2147483648");
   1588   EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
   1589   env_->NewString(nullptr, -1);
   1590   jni_abort_catcher.Check("negative jsize: -1");
   1591   env_->NewString(nullptr, std::numeric_limits<jint>::min());
   1592   jni_abort_catcher.Check("negative jsize: -2147483648");
   1593   EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
   1594 }
   1595 
   1596 TEST_F(JniInternalTest, GetStringLength_GetStringUTFLength) {
   1597   // Already tested in the NewString/NewStringUTF tests.
   1598 }
   1599 
   1600 TEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) {
   1601   jstring s = env_->NewStringUTF("hello");
   1602   ASSERT_TRUE(s != nullptr);
   1603 
   1604   env_->GetStringRegion(s, -1, 0, nullptr);
   1605   ExpectException(sioobe_);
   1606   env_->GetStringRegion(s, 0, -1, nullptr);
   1607   ExpectException(sioobe_);
   1608   env_->GetStringRegion(s, 0, 10, nullptr);
   1609   ExpectException(sioobe_);
   1610   env_->GetStringRegion(s, 10, 1, nullptr);
   1611   ExpectException(sioobe_);
   1612   // Regression test against integer overflow in range check.
   1613   env_->GetStringRegion(s, 0x7fffffff, 0x7fffffff, nullptr);
   1614   ExpectException(sioobe_);
   1615 
   1616   jchar chars[4] = { 'x', 'x', 'x', 'x' };
   1617   env_->GetStringRegion(s, 1, 2, &chars[1]);
   1618   EXPECT_EQ('x', chars[0]);
   1619   EXPECT_EQ('e', chars[1]);
   1620   EXPECT_EQ('l', chars[2]);
   1621   EXPECT_EQ('x', chars[3]);
   1622 
   1623   // It's okay for the buffer to be null as long as the length is 0.
   1624   env_->GetStringRegion(s, 2, 0, nullptr);
   1625   // Even if the offset is invalid...
   1626   env_->GetStringRegion(s, 123, 0, nullptr);
   1627   ExpectException(sioobe_);
   1628 
   1629   env_->GetStringUTFRegion(s, -1, 0, nullptr);
   1630   ExpectException(sioobe_);
   1631   env_->GetStringUTFRegion(s, 0, -1, nullptr);
   1632   ExpectException(sioobe_);
   1633   env_->GetStringUTFRegion(s, 0, 10, nullptr);
   1634   ExpectException(sioobe_);
   1635   env_->GetStringUTFRegion(s, 10, 1, nullptr);
   1636   ExpectException(sioobe_);
   1637   // Regression test against integer overflow in range check.
   1638   env_->GetStringUTFRegion(s, 0x7fffffff, 0x7fffffff, nullptr);
   1639   ExpectException(sioobe_);
   1640 
   1641   char bytes[4] = { 'x', 'x', 'x', 'x' };
   1642   env_->GetStringUTFRegion(s, 1, 2, &bytes[1]);
   1643   EXPECT_EQ('x', bytes[0]);
   1644   EXPECT_EQ('e', bytes[1]);
   1645   EXPECT_EQ('l', bytes[2]);
   1646   EXPECT_EQ('x', bytes[3]);
   1647 
   1648   // It's okay for the buffer to be null as long as the length is 0.
   1649   env_->GetStringUTFRegion(s, 2, 0, nullptr);
   1650   // Even if the offset is invalid...
   1651   env_->GetStringUTFRegion(s, 123, 0, nullptr);
   1652   ExpectException(sioobe_);
   1653 }
   1654 
   1655 TEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) {
   1656   // Passing in a null jstring is ignored normally, but caught by -Xcheck:jni.
   1657   bool old_check_jni = vm_->SetCheckJniEnabled(false);
   1658   {
   1659     CheckJniAbortCatcher check_jni_abort_catcher;
   1660     EXPECT_EQ(env_->GetStringUTFChars(nullptr, nullptr), nullptr);
   1661   }
   1662   {
   1663     CheckJniAbortCatcher check_jni_abort_catcher;
   1664     EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
   1665     EXPECT_EQ(env_->GetStringUTFChars(nullptr, nullptr), nullptr);
   1666     check_jni_abort_catcher.Check("GetStringUTFChars received NULL jstring");
   1667     EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
   1668   }
   1669 
   1670   jstring s = env_->NewStringUTF("hello");
   1671   ASSERT_TRUE(s != nullptr);
   1672 
   1673   const char* utf = env_->GetStringUTFChars(s, nullptr);
   1674   EXPECT_STREQ("hello", utf);
   1675   env_->ReleaseStringUTFChars(s, utf);
   1676 
   1677   jboolean is_copy = JNI_FALSE;
   1678   utf = env_->GetStringUTFChars(s, &is_copy);
   1679   EXPECT_EQ(JNI_TRUE, is_copy);
   1680   EXPECT_STREQ("hello", utf);
   1681   env_->ReleaseStringUTFChars(s, utf);
   1682 }
   1683 
   1684 TEST_F(JniInternalTest, GetStringChars_ReleaseStringChars) {
   1685   jstring s = env_->NewStringUTF("hello");
   1686   ScopedObjectAccess soa(env_);
   1687   ObjPtr<mirror::String> s_m = soa.Decode<mirror::String>(s);
   1688   ASSERT_TRUE(s != nullptr);
   1689 
   1690   jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
   1691   const jchar* chars = env_->GetStringChars(s, nullptr);
   1692   EXPECT_EQ(expected[0], chars[0]);
   1693   EXPECT_EQ(expected[1], chars[1]);
   1694   EXPECT_EQ(expected[2], chars[2]);
   1695   EXPECT_EQ(expected[3], chars[3]);
   1696   EXPECT_EQ(expected[4], chars[4]);
   1697   env_->ReleaseStringChars(s, chars);
   1698 
   1699   jboolean is_copy = JNI_FALSE;
   1700   chars = env_->GetStringChars(s, &is_copy);
   1701   if (Runtime::Current()->GetHeap()->IsMovableObject(s_m)) {
   1702     EXPECT_EQ(JNI_TRUE, is_copy);
   1703   } else {
   1704     EXPECT_EQ(JNI_FALSE, is_copy);
   1705   }
   1706   EXPECT_EQ(expected[0], chars[0]);
   1707   EXPECT_EQ(expected[1], chars[1]);
   1708   EXPECT_EQ(expected[2], chars[2]);
   1709   EXPECT_EQ(expected[3], chars[3]);
   1710   EXPECT_EQ(expected[4], chars[4]);
   1711   env_->ReleaseStringChars(s, chars);
   1712 }
   1713 
   1714 TEST_F(JniInternalTest, GetStringCritical_ReleaseStringCritical) {
   1715   jstring s = env_->NewStringUTF("hello");
   1716   ASSERT_TRUE(s != nullptr);
   1717 
   1718   jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
   1719   const jchar* chars = env_->GetStringCritical(s, nullptr);
   1720   EXPECT_EQ(expected[0], chars[0]);
   1721   EXPECT_EQ(expected[1], chars[1]);
   1722   EXPECT_EQ(expected[2], chars[2]);
   1723   EXPECT_EQ(expected[3], chars[3]);
   1724   EXPECT_EQ(expected[4], chars[4]);
   1725   env_->ReleaseStringCritical(s, chars);
   1726 
   1727   jboolean is_copy = JNI_TRUE;
   1728   chars = env_->GetStringCritical(s, &is_copy);
   1729   if (mirror::kUseStringCompression) {
   1730     // is_copy has to be JNI_TRUE because "hello" is all-ASCII
   1731     EXPECT_EQ(JNI_TRUE, is_copy);
   1732   } else {
   1733     EXPECT_EQ(JNI_FALSE, is_copy);
   1734   }
   1735   EXPECT_EQ(expected[0], chars[0]);
   1736   EXPECT_EQ(expected[1], chars[1]);
   1737   EXPECT_EQ(expected[2], chars[2]);
   1738   EXPECT_EQ(expected[3], chars[3]);
   1739   EXPECT_EQ(expected[4], chars[4]);
   1740   env_->ReleaseStringCritical(s, chars);
   1741 
   1742   if (mirror::kUseStringCompression) {
   1743     // is_copy has to be JNI_FALSE because "\xed\xa0\x81\xed\xb0\x80" is incompressible
   1744     jboolean is_copy_16 = JNI_TRUE;
   1745     jstring s_16 = env_->NewStringUTF("\xed\xa0\x81\xed\xb0\x80");
   1746     chars = env_->GetStringCritical(s_16, &is_copy_16);
   1747     EXPECT_EQ(2, env_->GetStringLength(s_16));
   1748     EXPECT_EQ(4, env_->GetStringUTFLength(s_16));
   1749     env_->ReleaseStringCritical(s_16, chars);
   1750   }
   1751 }
   1752 
   1753 TEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) {
   1754   jclass java_lang_Class = env_->FindClass("java/lang/Class");
   1755   ASSERT_TRUE(java_lang_Class != nullptr);
   1756 
   1757   jobjectArray array = env_->NewObjectArray(1, java_lang_Class, nullptr);
   1758   EXPECT_NE(array, nullptr);
   1759   EXPECT_EQ(env_->GetObjectArrayElement(array, 0), nullptr);
   1760   env_->SetObjectArrayElement(array, 0, java_lang_Class);
   1761   EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), java_lang_Class));
   1762 
   1763   // ArrayIndexOutOfBounds for negative index.
   1764   env_->SetObjectArrayElement(array, -1, java_lang_Class);
   1765   ExpectException(aioobe_);
   1766 
   1767   // ArrayIndexOutOfBounds for too-large index.
   1768   env_->SetObjectArrayElement(array, 1, java_lang_Class);
   1769   ExpectException(aioobe_);
   1770 
   1771   // ArrayStoreException thrown for bad types.
   1772   env_->SetObjectArrayElement(array, 0, env_->NewStringUTF("not a jclass!"));
   1773   ExpectException(ase_);
   1774 
   1775   // Null as array should fail.
   1776   CheckJniAbortCatcher jni_abort_catcher;
   1777   bool old_check_jni = vm_->SetCheckJniEnabled(false);
   1778   EXPECT_EQ(nullptr, env_->GetObjectArrayElement(nullptr, 0));
   1779   jni_abort_catcher.Check("java_array == null");
   1780   env_->SetObjectArrayElement(nullptr, 0, nullptr);
   1781   jni_abort_catcher.Check("java_array == null");
   1782   EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
   1783   EXPECT_EQ(nullptr, env_->GetObjectArrayElement(nullptr, 0));
   1784   jni_abort_catcher.Check("jarray was NULL");
   1785   env_->SetObjectArrayElement(nullptr, 0, nullptr);
   1786   jni_abort_catcher.Check("jarray was NULL");
   1787   EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
   1788 }
   1789 
   1790 #define EXPECT_STATIC_PRIMITIVE_FIELD(expect_eq, type, field_name, sig, value1, value2) \
   1791   do { \
   1792     jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \
   1793     EXPECT_NE(fid, nullptr); \
   1794     env_->SetStatic ## type ## Field(c, fid, value1); \
   1795     expect_eq(value1, env_->GetStatic ## type ## Field(c, fid)); \
   1796     env_->SetStatic ## type ## Field(c, fid, value2); \
   1797     expect_eq(value2, env_->GetStatic ## type ## Field(c, fid)); \
   1798     \
   1799     bool old_check_jni = vm_->SetCheckJniEnabled(false); \
   1800     { \
   1801       CheckJniAbortCatcher jni_abort_catcher; \
   1802       env_->GetStatic ## type ## Field(nullptr, fid); \
   1803       env_->SetStatic ## type ## Field(nullptr, fid, value1); \
   1804     } \
   1805     CheckJniAbortCatcher jni_abort_catcher; \
   1806     env_->GetStatic ## type ## Field(c, nullptr); \
   1807     jni_abort_catcher.Check("fid == null"); \
   1808     env_->SetStatic ## type ## Field(c, nullptr, value1); \
   1809     jni_abort_catcher.Check("fid == null"); \
   1810     \
   1811     EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); \
   1812     env_->GetStatic ## type ## Field(nullptr, fid); \
   1813     jni_abort_catcher.Check("received NULL jclass"); \
   1814     env_->SetStatic ## type ## Field(nullptr, fid, value1); \
   1815     jni_abort_catcher.Check("received NULL jclass"); \
   1816     env_->GetStatic ## type ## Field(c, nullptr); \
   1817     jni_abort_catcher.Check("jfieldID was NULL"); \
   1818     env_->SetStatic ## type ## Field(c, nullptr, value1); \
   1819     jni_abort_catcher.Check("jfieldID was NULL"); \
   1820     EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); \
   1821   } while (false)
   1822 
   1823 #define EXPECT_PRIMITIVE_FIELD(expect_eq, instance, type, field_name, sig, value1, value2) \
   1824   do { \
   1825     jfieldID fid = env_->GetFieldID(c, field_name, sig); \
   1826     EXPECT_NE(fid, nullptr); \
   1827     env_->Set ## type ## Field(instance, fid, value1); \
   1828     expect_eq(value1, env_->Get ## type ## Field(instance, fid)); \
   1829     env_->Set ## type ## Field(instance, fid, value2); \
   1830     expect_eq(value2, env_->Get ## type ## Field(instance, fid)); \
   1831     \
   1832     bool old_check_jni = vm_->SetCheckJniEnabled(false); \
   1833     CheckJniAbortCatcher jni_abort_catcher; \
   1834     env_->Get ## type ## Field(nullptr, fid); \
   1835     jni_abort_catcher.Check("obj == null"); \
   1836     env_->Set ## type ## Field(nullptr, fid, value1); \
   1837     jni_abort_catcher.Check("obj == null"); \
   1838     env_->Get ## type ## Field(instance, nullptr); \
   1839     jni_abort_catcher.Check("fid == null"); \
   1840     env_->Set ## type ## Field(instance, nullptr, value1); \
   1841     jni_abort_catcher.Check("fid == null"); \
   1842     EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); \
   1843     env_->Get ## type ## Field(nullptr, fid); \
   1844     jni_abort_catcher.Check("field operation on NULL object:"); \
   1845     env_->Set ## type ## Field(nullptr, fid, value1); \
   1846     jni_abort_catcher.Check("field operation on NULL object:"); \
   1847     env_->Get ## type ## Field(instance, nullptr); \
   1848     jni_abort_catcher.Check("jfieldID was NULL"); \
   1849     env_->Set ## type ## Field(instance, nullptr, value1); \
   1850     jni_abort_catcher.Check("jfieldID was NULL"); \
   1851     EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); \
   1852   } while (false)
   1853 
   1854 #define TEST_PRIMITIVE_FIELD_FOR_CLASS(cname) \
   1855   do {  \
   1856     Thread::Current()->TransitionFromSuspendedToRunnable(); \
   1857     LoadDex("AllFields"); \
   1858     bool started = runtime_->Start(); \
   1859     ASSERT_TRUE(started); \
   1860     jclass c = env_->FindClass(cname); \
   1861     ASSERT_NE(c, nullptr); \
   1862     jobject o = env_->AllocObject(c); \
   1863     ASSERT_NE(o, nullptr); \
   1864     \
   1865     EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Boolean, "sZ", "Z", JNI_TRUE, JNI_FALSE); \
   1866     EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Byte, "sB", "B", 1, 2); \
   1867     EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Char, "sC", "C", 'a', 'b'); \
   1868     EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_DOUBLE_EQ, Double, "sD", "D", 1.0, 2.0); \
   1869     EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_FLOAT_EQ, Float, "sF", "F", 1.0, 2.0); \
   1870     EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Int, "sI", "I", 1, 2); \
   1871     EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Long, "sJ", "J", 1, 2); \
   1872     EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Short, "sS", "S", 1, 2); \
   1873     \
   1874     EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Boolean, "iZ", "Z", JNI_TRUE, JNI_FALSE); \
   1875     EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Byte, "iB", "B", 1, 2); \
   1876     EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Char, "iC", "C", 'a', 'b'); \
   1877     EXPECT_PRIMITIVE_FIELD(EXPECT_DOUBLE_EQ, o, Double, "iD", "D", 1.0, 2.0); \
   1878     EXPECT_PRIMITIVE_FIELD(EXPECT_FLOAT_EQ, o, Float, "iF", "F", 1.0, 2.0); \
   1879     EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Int, "iI", "I", 1, 2); \
   1880     EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Long, "iJ", "J", 1, 2); \
   1881     EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Short, "iS", "S", 1, 2); \
   1882   } while (false)
   1883 
   1884 TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) {
   1885   TEST_PRIMITIVE_FIELD_FOR_CLASS("AllFields");
   1886 }
   1887 
   1888 TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField_Subclass) {
   1889   TEST_PRIMITIVE_FIELD_FOR_CLASS("AllFieldsSub");
   1890 }
   1891 
   1892 #define EXPECT_UNRELATED_FIELD_FAILURE(type, field_name, sig, value1) \
   1893   do { \
   1894     jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \
   1895     EXPECT_NE(fid, nullptr); \
   1896     CheckJniAbortCatcher jni_abort_catcher; \
   1897     env_->Get ## type ## Field(uc, fid); \
   1898     jni_abort_catcher.Check("not valid for an object of class"); \
   1899     env_->Set ## type ## Field(uc, fid, value1); \
   1900     jni_abort_catcher.Check("not valid for an object of class"); \
   1901   } while (false)
   1902 
   1903 TEST_F(JniInternalTest, GetField_SetField_unrelated) {
   1904   Thread::Current()->TransitionFromSuspendedToRunnable();
   1905   LoadDex("AllFields");
   1906   bool started = runtime_->Start();
   1907   ASSERT_TRUE(started);
   1908   jclass c = env_->FindClass("AllFields");
   1909   ASSERT_NE(c, nullptr);
   1910   jclass uc = env_->FindClass("AllFieldsUnrelated");
   1911   ASSERT_NE(uc, nullptr);
   1912   bool old_check_jni = vm_->SetCheckJniEnabled(true);
   1913   EXPECT_UNRELATED_FIELD_FAILURE(Boolean, "sZ", "Z", JNI_TRUE);
   1914   EXPECT_UNRELATED_FIELD_FAILURE(Byte, "sB", "B", 1);
   1915   EXPECT_UNRELATED_FIELD_FAILURE(Char, "sC", "C", 'a');
   1916   EXPECT_UNRELATED_FIELD_FAILURE(Double, "sD", "D", 1.0);
   1917   EXPECT_UNRELATED_FIELD_FAILURE(Float, "sF", "F", 1.0);
   1918   EXPECT_UNRELATED_FIELD_FAILURE(Int, "sI", "I", 1);
   1919   EXPECT_UNRELATED_FIELD_FAILURE(Long, "sJ", "J", 1);
   1920   EXPECT_UNRELATED_FIELD_FAILURE(Short, "sS", "S", 1);
   1921   EXPECT_UNRELATED_FIELD_FAILURE(Object, "sObject", "Ljava/lang/Object;", c);
   1922   EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
   1923 }
   1924 
   1925 #define TEST_OBJECT_FIELD_FOR_CLASS(cname) \
   1926   do { \
   1927     Thread::Current()->TransitionFromSuspendedToRunnable(); \
   1928     LoadDex("AllFields"); \
   1929     runtime_->Start(); \
   1930     \
   1931     jclass c = env_->FindClass(cname); \
   1932     ASSERT_NE(c, nullptr); \
   1933     jobject o = env_->AllocObject(c); \
   1934     ASSERT_NE(o, nullptr); \
   1935     \
   1936     jstring s1 = env_->NewStringUTF("hello"); \
   1937     ASSERT_NE(s1, nullptr); \
   1938     jstring s2 = env_->NewStringUTF("world"); \
   1939     ASSERT_NE(s2, nullptr); \
   1940     \
   1941     jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;"); \
   1942     ASSERT_NE(s_fid, nullptr); \
   1943     jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;"); \
   1944     ASSERT_NE(i_fid, nullptr); \
   1945     \
   1946     env_->SetStaticObjectField(c, s_fid, s1); \
   1947     ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid))); \
   1948     env_->SetStaticObjectField(c, s_fid, s2); \
   1949     ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid))); \
   1950     \
   1951     env_->SetObjectField(o, i_fid, s1); \
   1952     ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid))); \
   1953     env_->SetObjectField(o, i_fid, s2); \
   1954     ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid))); \
   1955   } while (false)
   1956 
   1957 TEST_F(JniInternalTest, GetObjectField_SetObjectField) {
   1958   TEST_OBJECT_FIELD_FOR_CLASS("AllFields");
   1959 }
   1960 
   1961 TEST_F(JniInternalTest, GetObjectField_SetObjectField_subclass) {
   1962   TEST_OBJECT_FIELD_FOR_CLASS("AllFieldsSub");
   1963 }
   1964 
   1965 TEST_F(JniInternalTest, NewLocalRef_nullptr) {
   1966   EXPECT_EQ(env_->NewLocalRef(nullptr), nullptr);
   1967 }
   1968 
   1969 TEST_F(JniInternalTest, NewLocalRef) {
   1970   jstring s = env_->NewStringUTF("");
   1971   ASSERT_NE(s, nullptr);
   1972   jobject o = env_->NewLocalRef(s);
   1973   EXPECT_NE(o, nullptr);
   1974   EXPECT_NE(o, s);
   1975 
   1976   EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(o));
   1977 }
   1978 
   1979 TEST_F(JniInternalTest, DeleteLocalRef_nullptr) {
   1980   env_->DeleteLocalRef(nullptr);
   1981 }
   1982 
   1983 TEST_F(JniInternalTest, DeleteLocalRef) {
   1984   // This tests leads to warnings and errors in the log.
   1985   ScopedLogSeverity sls(LogSeverity::FATAL);
   1986 
   1987   jstring s = env_->NewStringUTF("");
   1988   ASSERT_NE(s, nullptr);
   1989   env_->DeleteLocalRef(s);
   1990 
   1991   // Currently, deleting an already-deleted reference is just a CheckJNI warning.
   1992   {
   1993     bool old_check_jni = vm_->SetCheckJniEnabled(false);
   1994     {
   1995       CheckJniAbortCatcher check_jni_abort_catcher;
   1996       env_->DeleteLocalRef(s);
   1997     }
   1998     CheckJniAbortCatcher check_jni_abort_catcher;
   1999     EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
   2000     env_->DeleteLocalRef(s);
   2001     std::string expected(StringPrintf("use of deleted local reference %p", s));
   2002     check_jni_abort_catcher.Check(expected.c_str());
   2003     EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
   2004   }
   2005 
   2006   s = env_->NewStringUTF("");
   2007   ASSERT_NE(s, nullptr);
   2008   jobject o = env_->NewLocalRef(s);
   2009   ASSERT_NE(o, nullptr);
   2010 
   2011   env_->DeleteLocalRef(s);
   2012   env_->DeleteLocalRef(o);
   2013 }
   2014 
   2015 TEST_F(JniInternalTest, PushLocalFrame_10395422) {
   2016   // The JNI specification is ambiguous about whether the given capacity is to be interpreted as a
   2017   // maximum or as a minimum, but it seems like it's supposed to be a minimum, and that's how
   2018   // Android historically treated it, and it's how the RI treats it. It's also the more useful
   2019   // interpretation!
   2020   ASSERT_EQ(JNI_OK, env_->PushLocalFrame(0));
   2021   env_->PopLocalFrame(nullptr);
   2022 
   2023   // The following two tests will print errors to the log.
   2024   ScopedLogSeverity sls(LogSeverity::FATAL);
   2025 
   2026   // Negative capacities are not allowed.
   2027   ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(-1));
   2028 }
   2029 
   2030 TEST_F(JniInternalTest, PushLocalFrame_PopLocalFrame) {
   2031   // This tests leads to errors in the log.
   2032   ScopedLogSeverity sls(LogSeverity::FATAL);
   2033 
   2034   jobject original = env_->NewStringUTF("");
   2035   ASSERT_NE(original, nullptr);
   2036 
   2037   jobject outer;
   2038   jobject inner1, inner2;
   2039   ScopedObjectAccess soa(env_);
   2040   {
   2041     ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
   2042     outer = env_->NewLocalRef(original);
   2043 
   2044     {
   2045       ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
   2046       inner1 = env_->NewLocalRef(outer);
   2047       inner2 = env_->NewStringUTF("survivor");
   2048       EXPECT_NE(env_->PopLocalFrame(inner2), nullptr);
   2049     }
   2050 
   2051     EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
   2052     EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(outer));
   2053     {
   2054       CheckJniAbortCatcher check_jni_abort_catcher;
   2055       EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
   2056       check_jni_abort_catcher.Check("use of deleted local reference");
   2057     }
   2058 
   2059     // Our local reference for the survivor is invalid because the survivor
   2060     // gets a new local reference...
   2061     {
   2062       CheckJniAbortCatcher check_jni_abort_catcher;
   2063       EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
   2064       check_jni_abort_catcher.Check("use of deleted local reference");
   2065     }
   2066 
   2067     EXPECT_EQ(env_->PopLocalFrame(nullptr), nullptr);
   2068   }
   2069   EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
   2070   CheckJniAbortCatcher check_jni_abort_catcher;
   2071   EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(outer));
   2072   check_jni_abort_catcher.Check("use of deleted local reference");
   2073   EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
   2074   check_jni_abort_catcher.Check("use of deleted local reference");
   2075   EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
   2076   check_jni_abort_catcher.Check("use of deleted local reference");
   2077 }
   2078 
   2079 TEST_F(JniInternalTest, PushLocalFrame_LimitAndOverflow) {
   2080   // Try a very large value that should fail.
   2081   ASSERT_NE(JNI_OK, env_->PushLocalFrame(std::numeric_limits<jint>::max()));
   2082   ASSERT_TRUE(env_->ExceptionCheck());
   2083   env_->ExceptionClear();
   2084 
   2085   // On 32-bit, also check for some overflow conditions.
   2086 #ifndef __LP64__
   2087   ASSERT_EQ(JNI_OK, env_->PushLocalFrame(10));
   2088   ASSERT_NE(JNI_OK, env_->PushLocalFrame(std::numeric_limits<jint>::max() - 10));
   2089   ASSERT_TRUE(env_->ExceptionCheck());
   2090   env_->ExceptionClear();
   2091   EXPECT_EQ(env_->PopLocalFrame(nullptr), nullptr);
   2092 #endif
   2093 }
   2094 
   2095 TEST_F(JniInternalTest, PushLocalFrame_b62223672) {
   2096   // The 512 entry limit has been lifted, try a larger value.
   2097   ASSERT_EQ(JNI_OK, env_->PushLocalFrame(1024));
   2098   EXPECT_EQ(env_->PopLocalFrame(nullptr), nullptr);
   2099 }
   2100 
   2101 TEST_F(JniInternalTest, NewGlobalRef_nullptr) {
   2102   EXPECT_EQ(env_->NewGlobalRef(nullptr), nullptr);
   2103 }
   2104 
   2105 TEST_F(JniInternalTest, NewGlobalRef) {
   2106   jstring s = env_->NewStringUTF("");
   2107   ASSERT_NE(s, nullptr);
   2108   jobject o = env_->NewGlobalRef(s);
   2109   EXPECT_NE(o, nullptr);
   2110   EXPECT_NE(o, s);
   2111 
   2112   EXPECT_EQ(env_->GetObjectRefType(o), JNIGlobalRefType);
   2113 }
   2114 
   2115 TEST_F(JniInternalTest, DeleteGlobalRef_nullptr) {
   2116   env_->DeleteGlobalRef(nullptr);
   2117 }
   2118 
   2119 TEST_F(JniInternalTest, DeleteGlobalRef) {
   2120   // This tests leads to warnings and errors in the log.
   2121   ScopedLogSeverity sls(LogSeverity::FATAL);
   2122 
   2123   jstring s = env_->NewStringUTF("");
   2124   ASSERT_NE(s, nullptr);
   2125 
   2126   jobject o = env_->NewGlobalRef(s);
   2127   ASSERT_NE(o, nullptr);
   2128   env_->DeleteGlobalRef(o);
   2129 
   2130   // Currently, deleting an already-deleted reference is just a CheckJNI warning.
   2131   {
   2132     bool old_check_jni = vm_->SetCheckJniEnabled(false);
   2133     {
   2134       CheckJniAbortCatcher check_jni_abort_catcher;
   2135       env_->DeleteGlobalRef(o);
   2136     }
   2137     CheckJniAbortCatcher check_jni_abort_catcher;
   2138     EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
   2139     env_->DeleteGlobalRef(o);
   2140     std::string expected(StringPrintf("use of deleted global reference %p", o));
   2141     check_jni_abort_catcher.Check(expected.c_str());
   2142     EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
   2143   }
   2144 
   2145   jobject o1 = env_->NewGlobalRef(s);
   2146   ASSERT_NE(o1, nullptr);
   2147   jobject o2 = env_->NewGlobalRef(s);
   2148   ASSERT_NE(o2, nullptr);
   2149 
   2150   env_->DeleteGlobalRef(o1);
   2151   env_->DeleteGlobalRef(o2);
   2152 }
   2153 
   2154 TEST_F(JniInternalTest, NewWeakGlobalRef_nullptr) {
   2155   EXPECT_EQ(env_->NewWeakGlobalRef(nullptr),   nullptr);
   2156 }
   2157 
   2158 TEST_F(JniInternalTest, NewWeakGlobalRef) {
   2159   jstring s = env_->NewStringUTF("");
   2160   ASSERT_NE(s, nullptr);
   2161   jobject o = env_->NewWeakGlobalRef(s);
   2162   EXPECT_NE(o, nullptr);
   2163   EXPECT_NE(o, s);
   2164 
   2165   EXPECT_EQ(env_->GetObjectRefType(o), JNIWeakGlobalRefType);
   2166 }
   2167 
   2168 TEST_F(JniInternalTest, DeleteWeakGlobalRef_nullptr) {
   2169   env_->DeleteWeakGlobalRef(nullptr);
   2170 }
   2171 
   2172 TEST_F(JniInternalTest, DeleteWeakGlobalRef) {
   2173   // This tests leads to warnings and errors in the log.
   2174   ScopedLogSeverity sls(LogSeverity::FATAL);
   2175 
   2176   jstring s = env_->NewStringUTF("");
   2177   ASSERT_NE(s, nullptr);
   2178 
   2179   jobject o = env_->NewWeakGlobalRef(s);
   2180   ASSERT_NE(o, nullptr);
   2181   env_->DeleteWeakGlobalRef(o);
   2182 
   2183   // Currently, deleting an already-deleted reference is just a CheckJNI warning.
   2184   {
   2185     bool old_check_jni = vm_->SetCheckJniEnabled(false);
   2186     {
   2187       CheckJniAbortCatcher check_jni_abort_catcher;
   2188       env_->DeleteWeakGlobalRef(o);
   2189     }
   2190     CheckJniAbortCatcher check_jni_abort_catcher;
   2191     EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
   2192     env_->DeleteWeakGlobalRef(o);
   2193     std::string expected(StringPrintf("use of deleted weak global reference %p", o));
   2194     check_jni_abort_catcher.Check(expected.c_str());
   2195     EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
   2196   }
   2197 
   2198   jobject o1 = env_->NewWeakGlobalRef(s);
   2199   ASSERT_NE(o1, nullptr);
   2200   jobject o2 = env_->NewWeakGlobalRef(s);
   2201   ASSERT_NE(o2, nullptr);
   2202 
   2203   env_->DeleteWeakGlobalRef(o1);
   2204   env_->DeleteWeakGlobalRef(o2);
   2205 }
   2206 
   2207 TEST_F(JniInternalTest, ExceptionDescribe) {
   2208   // This checks how ExceptionDescribe handles call without exception.
   2209   env_->ExceptionClear();
   2210   env_->ExceptionDescribe();
   2211 }
   2212 
   2213 TEST_F(JniInternalTest, Throw) {
   2214   jclass exception_class = env_->FindClass("java/lang/RuntimeException");
   2215   ASSERT_TRUE(exception_class != nullptr);
   2216   jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class));
   2217   ASSERT_TRUE(exception != nullptr);
   2218 
   2219   EXPECT_EQ(JNI_OK, env_->Throw(exception));
   2220   EXPECT_TRUE(env_->ExceptionCheck());
   2221   jthrowable thrown_exception = env_->ExceptionOccurred();
   2222   env_->ExceptionClear();
   2223   EXPECT_TRUE(env_->IsSameObject(exception, thrown_exception));
   2224 
   2225   // Bad argument.
   2226   bool old_check_jni = vm_->SetCheckJniEnabled(false);
   2227   EXPECT_EQ(JNI_ERR, env_->Throw(nullptr));
   2228   EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
   2229   CheckJniAbortCatcher check_jni_abort_catcher;
   2230   EXPECT_EQ(JNI_ERR, env_->Throw(nullptr));
   2231   check_jni_abort_catcher.Check("Throw received NULL jthrowable");
   2232   EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
   2233 }
   2234 
   2235 TEST_F(JniInternalTest, ThrowNew) {
   2236   jclass exception_class = env_->FindClass("java/lang/RuntimeException");
   2237   ASSERT_TRUE(exception_class != nullptr);
   2238 
   2239   jthrowable thrown_exception;
   2240 
   2241   EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
   2242   EXPECT_TRUE(env_->ExceptionCheck());
   2243   thrown_exception = env_->ExceptionOccurred();
   2244   env_->ExceptionClear();
   2245   EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
   2246 
   2247   EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, nullptr));
   2248   EXPECT_TRUE(env_->ExceptionCheck());
   2249   thrown_exception = env_->ExceptionOccurred();
   2250   env_->ExceptionClear();
   2251   EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
   2252 
   2253   // Bad argument.
   2254   bool old_check_jni = vm_->SetCheckJniEnabled(false);
   2255   CheckJniAbortCatcher check_jni_abort_catcher;
   2256   EXPECT_EQ(JNI_ERR, env_->ThrowNew(nullptr, nullptr));
   2257   check_jni_abort_catcher.Check("c == null");
   2258   EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
   2259   EXPECT_EQ(JNI_ERR, env_->ThrowNew(nullptr, nullptr));
   2260   check_jni_abort_catcher.Check("ThrowNew received NULL jclass");
   2261   EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
   2262 }
   2263 
   2264 TEST_F(JniInternalTest, NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) {
   2265   // Start runtime.
   2266   Thread* self = Thread::Current();
   2267   self->TransitionFromSuspendedToRunnable();
   2268   MakeExecutable(nullptr, "java.lang.Class");
   2269   MakeExecutable(nullptr, "java.lang.Object");
   2270   MakeExecutable(nullptr, "java.nio.DirectByteBuffer");
   2271   MakeExecutable(nullptr, "java.nio.Bits");
   2272   MakeExecutable(nullptr, "java.nio.MappedByteBuffer");
   2273   MakeExecutable(nullptr, "java.nio.ByteBuffer");
   2274   MakeExecutable(nullptr, "java.nio.Buffer");
   2275   // TODO: we only load a dex file here as starting the runtime relies upon it.
   2276   const char* class_name = "StaticLeafMethods";
   2277   LoadDex(class_name);
   2278   bool started = runtime_->Start();
   2279   ASSERT_TRUE(started);
   2280 
   2281   jclass buffer_class = env_->FindClass("java/nio/Buffer");
   2282   ASSERT_NE(buffer_class, nullptr);
   2283 
   2284   char bytes[1024];
   2285   jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes));
   2286   ASSERT_NE(buffer, nullptr);
   2287   ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class));
   2288   ASSERT_EQ(env_->GetDirectBufferAddress(buffer), bytes);
   2289   ASSERT_EQ(env_->GetDirectBufferCapacity(buffer), static_cast<jlong>(sizeof(bytes)));
   2290 
   2291   {
   2292     CheckJniAbortCatcher check_jni_abort_catcher;
   2293     env_->NewDirectByteBuffer(bytes, static_cast<jlong>(INT_MAX) + 1);
   2294     check_jni_abort_catcher.Check("in call to NewDirectByteBuffer");
   2295   }
   2296 }
   2297 
   2298 TEST_F(JniInternalTest, MonitorEnterExit) {
   2299   // This will print some error messages. Suppress.
   2300   ScopedLogSeverity sls(LogSeverity::FATAL);
   2301 
   2302   // Create an object to torture.
   2303   jclass object_class = env_->FindClass("java/lang/Object");
   2304   ASSERT_NE(object_class, nullptr);
   2305   jobject object = env_->AllocObject(object_class);
   2306   ASSERT_NE(object, nullptr);
   2307 
   2308   // Expected class of exceptions
   2309   jclass imse_class = env_->FindClass("java/lang/IllegalMonitorStateException");
   2310   ASSERT_NE(imse_class, nullptr);
   2311 
   2312   jthrowable thrown_exception;
   2313 
   2314   // Unlock of unowned monitor
   2315   env_->MonitorExit(object);
   2316   EXPECT_TRUE(env_->ExceptionCheck());
   2317   thrown_exception = env_->ExceptionOccurred();
   2318   env_->ExceptionClear();
   2319   EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
   2320 
   2321   // Lock of unowned monitor
   2322   env_->MonitorEnter(object);
   2323   EXPECT_FALSE(env_->ExceptionCheck());
   2324   // Regular unlock
   2325   env_->MonitorExit(object);
   2326   EXPECT_FALSE(env_->ExceptionCheck());
   2327 
   2328   // Recursively lock a lot
   2329   size_t max_recursive_lock = 1024;
   2330   for (size_t i = 0; i < max_recursive_lock; i++) {
   2331     env_->MonitorEnter(object);
   2332     EXPECT_FALSE(env_->ExceptionCheck());
   2333   }
   2334   // Recursively unlock a lot
   2335   for (size_t i = 0; i < max_recursive_lock; i++) {
   2336     env_->MonitorExit(object);
   2337     EXPECT_FALSE(env_->ExceptionCheck());
   2338   }
   2339 
   2340   // Unlock of unowned monitor
   2341   env_->MonitorExit(object);
   2342   EXPECT_TRUE(env_->ExceptionCheck());
   2343   thrown_exception = env_->ExceptionOccurred();
   2344   env_->ExceptionClear();
   2345   EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
   2346 
   2347   // It's an error to call MonitorEnter or MonitorExit on null.
   2348   {
   2349     CheckJniAbortCatcher check_jni_abort_catcher;
   2350     env_->MonitorEnter(nullptr);
   2351     check_jni_abort_catcher.Check("in call to MonitorEnter");
   2352     env_->MonitorExit(nullptr);
   2353     check_jni_abort_catcher.Check("in call to MonitorExit");
   2354   }
   2355 }
   2356 
   2357 void Java_MyClassNatives_foo_exit(JNIEnv* env, jobject thisObj) {
   2358   // Release the monitor on self. This should trigger an abort.
   2359   env->MonitorExit(thisObj);
   2360 }
   2361 
   2362 TEST_F(JniInternalTest, MonitorExitLockedInDifferentCall) {
   2363   SetUpForTest(false, "foo", "()V", reinterpret_cast<void*>(&Java_MyClassNatives_foo_exit));
   2364   ASSERT_NE(jobj_, nullptr);
   2365 
   2366   env_->MonitorEnter(jobj_);
   2367   EXPECT_FALSE(env_->ExceptionCheck());
   2368 
   2369   CheckJniAbortCatcher check_jni_abort_catcher;
   2370   env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
   2371   check_jni_abort_catcher.Check("Unlocking monitor that wasn't locked here");
   2372 }
   2373 
   2374 void Java_MyClassNatives_foo_enter_no_exit(JNIEnv* env, jobject thisObj) {
   2375   // Acquire but don't release the monitor on self. This should trigger an abort on return.
   2376   env->MonitorEnter(thisObj);
   2377 }
   2378 
   2379 TEST_F(JniInternalTest, MonitorExitNotAllUnlocked) {
   2380   SetUpForTest(false,
   2381                "foo",
   2382                "()V",
   2383                reinterpret_cast<void*>(&Java_MyClassNatives_foo_enter_no_exit));
   2384   ASSERT_NE(jobj_, nullptr);
   2385 
   2386   CheckJniAbortCatcher check_jni_abort_catcher;
   2387   env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
   2388   check_jni_abort_catcher.Check("Still holding a locked object on JNI end");
   2389 }
   2390 
   2391 static bool IsLocked(JNIEnv* env, jobject jobj) {
   2392   ScopedObjectAccess soa(env);
   2393   LockWord lock_word = soa.Decode<mirror::Object>(jobj)->GetLockWord(true);
   2394   switch (lock_word.GetState()) {
   2395     case LockWord::kHashCode:
   2396     case LockWord::kUnlocked:
   2397       return false;
   2398     case LockWord::kThinLocked:
   2399       return true;
   2400     case LockWord::kFatLocked:
   2401       return lock_word.FatLockMonitor()->IsLocked();
   2402     default: {
   2403       LOG(FATAL) << "Invalid monitor state " << lock_word.GetState();
   2404       UNREACHABLE();
   2405     }
   2406   }
   2407 }
   2408 
   2409 TEST_F(JniInternalTest, DetachThreadUnlockJNIMonitors) {
   2410   // We need to lock an object, detach, reattach, and check the locks.
   2411   //
   2412   // As re-attaching will create a different thread, we need to use a global
   2413   // ref to keep the object around.
   2414 
   2415   // Create an object to torture.
   2416   jobject global_ref;
   2417   {
   2418     jclass object_class = env_->FindClass("java/lang/Object");
   2419     ASSERT_NE(object_class, nullptr);
   2420     jobject object = env_->AllocObject(object_class);
   2421     ASSERT_NE(object, nullptr);
   2422     global_ref = env_->NewGlobalRef(object);
   2423   }
   2424 
   2425   // Lock it.
   2426   env_->MonitorEnter(global_ref);
   2427   ASSERT_TRUE(IsLocked(env_, global_ref));
   2428 
   2429   // Detach and re-attach.
   2430   jint detach_result = vm_->DetachCurrentThread();
   2431   ASSERT_EQ(detach_result, JNI_OK);
   2432   jint attach_result = vm_->AttachCurrentThread(&env_, nullptr);
   2433   ASSERT_EQ(attach_result, JNI_OK);
   2434 
   2435   // Look at the global ref, check whether it's still locked.
   2436   ASSERT_FALSE(IsLocked(env_, global_ref));
   2437 
   2438   // Delete the global ref.
   2439   env_->DeleteGlobalRef(global_ref);
   2440 }
   2441 
   2442 // Test the offset computation of IndirectReferenceTable offsets. b/26071368.
   2443 TEST_F(JniInternalTest, IndirectReferenceTableOffsets) {
   2444   // The segment_state_ field is private, and we want to avoid friend declaration. So we'll check
   2445   // by modifying memory.
   2446   // The parameters don't really matter here.
   2447   std::string error_msg;
   2448   IndirectReferenceTable irt(5,
   2449                              IndirectRefKind::kGlobal,
   2450                              IndirectReferenceTable::ResizableCapacity::kNo,
   2451                              &error_msg);
   2452   ASSERT_TRUE(irt.IsValid()) << error_msg;
   2453   IRTSegmentState old_state = irt.GetSegmentState();
   2454 
   2455   // Write some new state directly. We invert parts of old_state to ensure a new value.
   2456   IRTSegmentState new_state;
   2457   new_state.top_index = old_state.top_index ^ 0x07705005;
   2458   ASSERT_NE(old_state.top_index, new_state.top_index);
   2459 
   2460   uint8_t* base = reinterpret_cast<uint8_t*>(&irt);
   2461   int32_t segment_state_offset =
   2462       IndirectReferenceTable::SegmentStateOffset(sizeof(void*)).Int32Value();
   2463   *reinterpret_cast<IRTSegmentState*>(base + segment_state_offset) = new_state;
   2464 
   2465   // Read and compare.
   2466   EXPECT_EQ(new_state.top_index, irt.GetSegmentState().top_index);
   2467 }
   2468 
   2469 // Test the offset computation of JNIEnvExt offsets. b/26071368.
   2470 TEST_F(JniInternalTest, JNIEnvExtOffsets) {
   2471   EXPECT_EQ(OFFSETOF_MEMBER(JNIEnvExt, local_ref_cookie_),
   2472             JNIEnvExt::LocalRefCookieOffset(sizeof(void*)).Uint32Value());
   2473 
   2474   EXPECT_EQ(OFFSETOF_MEMBER(JNIEnvExt, self_), JNIEnvExt::SelfOffset(sizeof(void*)).Uint32Value());
   2475 
   2476   // segment_state_ is private in the IndirectReferenceTable. So this test isn't as good as we'd
   2477   // hope it to be.
   2478   uint32_t segment_state_now =
   2479       OFFSETOF_MEMBER(JNIEnvExt, locals_) +
   2480       IndirectReferenceTable::SegmentStateOffset(sizeof(void*)).Uint32Value();
   2481   uint32_t segment_state_computed = JNIEnvExt::SegmentStateOffset(sizeof(void*)).Uint32Value();
   2482   EXPECT_EQ(segment_state_now, segment_state_computed);
   2483 }
   2484 
   2485 static size_t gGlobalRefCount = 0;
   2486 static const JNINativeInterface* gOriginalEnv = nullptr;
   2487 
   2488 static jobject CountNewGlobalRef(JNIEnv* env, jobject o) {
   2489   ++gGlobalRefCount;
   2490   return gOriginalEnv->NewGlobalRef(env, o);
   2491 }
   2492 
   2493 // Test the table override.
   2494 TEST_F(JniInternalTest, JNIEnvExtTableOverride) {
   2495   JNINativeInterface env_override;
   2496   memcpy(&env_override, env_->functions, sizeof(JNINativeInterface));
   2497 
   2498   gOriginalEnv = env_->functions;
   2499   env_override.NewGlobalRef = CountNewGlobalRef;
   2500   gGlobalRefCount = 0;
   2501 
   2502   jclass local = env_->FindClass("java/lang/Object");
   2503   ASSERT_TRUE(local != nullptr);
   2504 
   2505   // Set the table, add a global ref, see whether the counter increases.
   2506   JNIEnvExt::SetTableOverride(&env_override);
   2507 
   2508   jobject global = env_->NewGlobalRef(local);
   2509   EXPECT_EQ(1u, gGlobalRefCount);
   2510   env_->DeleteGlobalRef(global);
   2511 
   2512   // Reset
   2513   JNIEnvExt::SetTableOverride(nullptr);
   2514 
   2515   jobject global2 = env_->NewGlobalRef(local);
   2516   EXPECT_EQ(1u, gGlobalRefCount);
   2517   env_->DeleteGlobalRef(global2);
   2518 }
   2519 
   2520 TEST_F(JniInternalTest, NonAttachedThread) {
   2521   // This tests leads to warnings and errors in the log.
   2522   ScopedLogSeverity sls(LogSeverity::FATAL);
   2523   CheckJniAbortCatcher check_jni_abort_catcher;
   2524 
   2525   auto callee = [](void* env_ptr) -> void* {
   2526     JNIEnv* env = reinterpret_cast<JNIEnv*>(env_ptr);
   2527     env->NewStringUTF("test");
   2528     return nullptr;
   2529   };
   2530 
   2531   bool old_check_jni = vm_->SetCheckJniEnabled(false);
   2532   vm_->SetCheckJniEnabled(true);
   2533   {
   2534     pthread_t pthread;
   2535     int pthread_create_result = pthread_create(&pthread,
   2536                                                /* pthread_attr */ nullptr,
   2537                                                callee,
   2538                                                reinterpret_cast<void*>(env_));
   2539     CHECK_EQ(pthread_create_result, 0);
   2540     int pthread_join_result = pthread_join(pthread, /* thread_return */ nullptr);
   2541     CHECK_EQ(pthread_join_result, 0);
   2542   }
   2543   vm_->SetCheckJniEnabled(old_check_jni);
   2544 
   2545   check_jni_abort_catcher.Check("is making JNI calls without being attached");
   2546 }
   2547 
   2548 }  // namespace art
   2549