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 "common_compiler_test.h"
     20 #include "mirror/art_method-inl.h"
     21 #include "mirror/string-inl.h"
     22 #include "scoped_thread_state_change.h"
     23 #include "ScopedLocalRef.h"
     24 
     25 namespace art {
     26 
     27 // TODO: Convert to CommonRuntimeTest. Currently MakeExecutable is used.
     28 class JniInternalTest : public CommonCompilerTest {
     29  protected:
     30   virtual void SetUp() {
     31     CommonCompilerTest::SetUp();
     32 
     33     vm_ = Runtime::Current()->GetJavaVM();
     34 
     35     // Turn on -verbose:jni for the JNI tests.
     36     // gLogVerbosity.jni = true;
     37 
     38     vm_->AttachCurrentThread(&env_, nullptr);
     39 
     40     ScopedLocalRef<jclass> aioobe(env_,
     41                                   env_->FindClass("java/lang/ArrayIndexOutOfBoundsException"));
     42     CHECK(aioobe.get() != nullptr);
     43     aioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(aioobe.get()));
     44 
     45     ScopedLocalRef<jclass> ase(env_, env_->FindClass("java/lang/ArrayStoreException"));
     46     CHECK(ase.get() != nullptr);
     47     ase_ = reinterpret_cast<jclass>(env_->NewGlobalRef(ase.get()));
     48 
     49     ScopedLocalRef<jclass> sioobe(env_,
     50                                   env_->FindClass("java/lang/StringIndexOutOfBoundsException"));
     51     CHECK(sioobe.get() != nullptr);
     52     sioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(sioobe.get()));
     53   }
     54 
     55   void ExpectException(jclass exception_class) {
     56     EXPECT_TRUE(env_->ExceptionCheck());
     57     jthrowable exception = env_->ExceptionOccurred();
     58     EXPECT_NE(nullptr, exception);
     59     env_->ExceptionClear();
     60     EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class));
     61   }
     62 
     63   void ExpectClassFound(const char* name) {
     64     EXPECT_NE(env_->FindClass(name), nullptr) << name;
     65     EXPECT_FALSE(env_->ExceptionCheck()) << name;
     66   }
     67 
     68   void ExpectClassNotFound(const char* name) {
     69     EXPECT_EQ(env_->FindClass(name), nullptr) << name;
     70     EXPECT_TRUE(env_->ExceptionCheck()) << name;
     71     env_->ExceptionClear();
     72   }
     73 
     74   void CleanUpJniEnv() {
     75     if (aioobe_ != nullptr) {
     76       env_->DeleteGlobalRef(aioobe_);
     77       aioobe_ = nullptr;
     78     }
     79     if (ase_ != nullptr) {
     80       env_->DeleteGlobalRef(ase_);
     81       ase_ = nullptr;
     82     }
     83     if (sioobe_ != nullptr) {
     84       env_->DeleteGlobalRef(sioobe_);
     85       sioobe_ = nullptr;
     86     }
     87   }
     88 
     89   virtual void TearDown() OVERRIDE {
     90     CleanUpJniEnv();
     91     CommonCompilerTest::TearDown();
     92   }
     93 
     94   jclass GetPrimitiveClass(char descriptor) {
     95     ScopedObjectAccess soa(env_);
     96     mirror::Class* c = class_linker_->FindPrimitiveClass(descriptor);
     97     CHECK(c != nullptr);
     98     return soa.AddLocalReference<jclass>(c);
     99   }
    100 
    101   JavaVMExt* vm_;
    102   JNIEnv* env_;
    103   jclass aioobe_;
    104   jclass ase_;
    105   jclass sioobe_;
    106 };
    107 
    108 TEST_F(JniInternalTest, AllocObject) {
    109   jclass c = env_->FindClass("java/lang/String");
    110   ASSERT_NE(c, nullptr);
    111   jobject o = env_->AllocObject(c);
    112   ASSERT_NE(o, nullptr);
    113 
    114   // We have an instance of the class we asked for...
    115   ASSERT_TRUE(env_->IsInstanceOf(o, c));
    116   // ...whose fields haven't been initialized because
    117   // we didn't call a constructor.
    118   ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "count", "I")));
    119   ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "offset", "I")));
    120   ASSERT_TRUE(env_->GetObjectField(o, env_->GetFieldID(c, "value", "[C")) == nullptr);
    121 }
    122 
    123 TEST_F(JniInternalTest, GetVersion) {
    124   ASSERT_EQ(JNI_VERSION_1_6, env_->GetVersion());
    125 }
    126 
    127 TEST_F(JniInternalTest, FindClass) {
    128   // Reference types...
    129   ExpectClassFound("java/lang/String");
    130   // ...for arrays too, where you must include "L;".
    131   ExpectClassFound("[Ljava/lang/String;");
    132   // Primitive arrays are okay too, if the primitive type is valid.
    133   ExpectClassFound("[C");
    134 
    135   {
    136     CheckJniAbortCatcher check_jni_abort_catcher;
    137     env_->FindClass(nullptr);
    138     check_jni_abort_catcher.Check("name == null");
    139 
    140     // We support . as well as / for compatibility, if -Xcheck:jni is off.
    141     ExpectClassFound("java.lang.String");
    142     check_jni_abort_catcher.Check("illegal class name 'java.lang.String'");
    143     ExpectClassNotFound("Ljava.lang.String;");
    144     check_jni_abort_catcher.Check("illegal class name 'Ljava.lang.String;'");
    145     ExpectClassFound("[Ljava.lang.String;");
    146     check_jni_abort_catcher.Check("illegal class name '[Ljava.lang.String;'");
    147     ExpectClassNotFound("[java.lang.String");
    148     check_jni_abort_catcher.Check("illegal class name '[java.lang.String'");
    149 
    150     // You can't include the "L;" in a JNI class descriptor.
    151     ExpectClassNotFound("Ljava/lang/String;");
    152     check_jni_abort_catcher.Check("illegal class name 'Ljava/lang/String;'");
    153 
    154     // But you must include it for an array of any reference type.
    155     ExpectClassNotFound("[java/lang/String");
    156     check_jni_abort_catcher.Check("illegal class name '[java/lang/String'");
    157 
    158     ExpectClassNotFound("[K");
    159     check_jni_abort_catcher.Check("illegal class name '[K'");
    160 
    161     // Void arrays aren't allowed.
    162     ExpectClassNotFound("[V");
    163     check_jni_abort_catcher.Check("illegal class name '[V'");
    164   }
    165 
    166   // But primitive types aren't allowed...
    167   ExpectClassNotFound("C");
    168   ExpectClassNotFound("V");
    169   ExpectClassNotFound("K");
    170 }
    171 
    172 TEST_F(JniInternalTest, GetFieldID) {
    173   jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
    174   ASSERT_NE(jlnsfe, nullptr);
    175   jclass c = env_->FindClass("java/lang/String");
    176   ASSERT_NE(c, nullptr);
    177 
    178   // Wrong type.
    179   jfieldID fid = env_->GetFieldID(c, "count", "J");
    180   EXPECT_EQ(nullptr, fid);
    181   ExpectException(jlnsfe);
    182 
    183   // Wrong type where type doesn't exist.
    184   fid = env_->GetFieldID(c, "count", "Lrod/jane/freddy;");
    185   EXPECT_EQ(nullptr, fid);
    186   ExpectException(jlnsfe);
    187 
    188   // Wrong name.
    189   fid = env_->GetFieldID(c, "Count", "I");
    190   EXPECT_EQ(nullptr, fid);
    191   ExpectException(jlnsfe);
    192 
    193   // Good declared field lookup.
    194   fid = env_->GetFieldID(c, "count", "I");
    195   EXPECT_NE(nullptr, fid);
    196   EXPECT_FALSE(env_->ExceptionCheck());
    197 
    198   // Good superclass field lookup.
    199   c = env_->FindClass("java/lang/StringBuilder");
    200   fid = env_->GetFieldID(c, "count", "I");
    201   EXPECT_NE(nullptr, fid);
    202   EXPECT_NE(fid, nullptr);
    203   EXPECT_FALSE(env_->ExceptionCheck());
    204 
    205   // Not instance.
    206   fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
    207   EXPECT_EQ(nullptr, fid);
    208   ExpectException(jlnsfe);
    209 
    210   // Bad arguments.
    211   CheckJniAbortCatcher check_jni_abort_catcher;
    212   fid = env_->GetFieldID(nullptr, "count", "I");
    213   EXPECT_EQ(nullptr, fid);
    214   check_jni_abort_catcher.Check("java_class == null");
    215   fid = env_->GetFieldID(c, nullptr, "I");
    216   EXPECT_EQ(nullptr, fid);
    217   check_jni_abort_catcher.Check("name == null");
    218   fid = env_->GetFieldID(c, "count", nullptr);
    219   EXPECT_EQ(nullptr, fid);
    220   check_jni_abort_catcher.Check("sig == null");
    221 }
    222 
    223 TEST_F(JniInternalTest, GetStaticFieldID) {
    224   jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
    225   ASSERT_NE(jlnsfe, nullptr);
    226   jclass c = env_->FindClass("java/lang/String");
    227   ASSERT_NE(c, nullptr);
    228 
    229   // Wrong type.
    230   jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J");
    231   EXPECT_EQ(nullptr, fid);
    232   ExpectException(jlnsfe);
    233 
    234   // Wrong type where type doesn't exist.
    235   fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Lrod/jane/freddy;");
    236   EXPECT_EQ(nullptr, fid);
    237   ExpectException(jlnsfe);
    238 
    239   // Wrong name.
    240   fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
    241   EXPECT_EQ(nullptr, fid);
    242   ExpectException(jlnsfe);
    243 
    244   // Good declared field lookup.
    245   fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
    246   EXPECT_NE(nullptr, fid);
    247   EXPECT_NE(fid, nullptr);
    248   EXPECT_FALSE(env_->ExceptionCheck());
    249 
    250   // Not static.
    251   fid = env_->GetStaticFieldID(c, "count", "I");
    252   EXPECT_EQ(nullptr, fid);
    253   ExpectException(jlnsfe);
    254 
    255   // Bad arguments.
    256   CheckJniAbortCatcher check_jni_abort_catcher;
    257   fid = env_->GetStaticFieldID(nullptr, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
    258   EXPECT_EQ(nullptr, fid);
    259   check_jni_abort_catcher.Check("java_class == null");
    260   fid = env_->GetStaticFieldID(c, nullptr, "Ljava/util/Comparator;");
    261   EXPECT_EQ(nullptr, fid);
    262   check_jni_abort_catcher.Check("name == null");
    263   fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", nullptr);
    264   EXPECT_EQ(nullptr, fid);
    265   check_jni_abort_catcher.Check("sig == null");
    266 }
    267 
    268 TEST_F(JniInternalTest, GetMethodID) {
    269   jclass jlobject = env_->FindClass("java/lang/Object");
    270   jclass jlstring = env_->FindClass("java/lang/String");
    271   jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
    272   jclass jncrbc = env_->FindClass("java/nio/channels/ReadableByteChannel");
    273 
    274   // Sanity check that no exceptions are pending.
    275   ASSERT_FALSE(env_->ExceptionCheck());
    276 
    277   // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
    278   // a pending exception.
    279   jmethodID method = env_->GetMethodID(jlobject, "foo", "()V");
    280   EXPECT_EQ(nullptr, method);
    281   ExpectException(jlnsme);
    282 
    283   // Check that java.lang.Object.equals() does exist.
    284   method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
    285   EXPECT_NE(nullptr, method);
    286   EXPECT_FALSE(env_->ExceptionCheck());
    287 
    288   // Check that GetMethodID for java.lang.String.valueOf(int) fails as the
    289   // method is static.
    290   method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
    291   EXPECT_EQ(nullptr, method);
    292   ExpectException(jlnsme);
    293 
    294   // Check that GetMethodID for java.lang.NoSuchMethodError.<init>(String) finds the constructor.
    295   method = env_->GetMethodID(jlnsme, "<init>", "(Ljava/lang/String;)V");
    296   EXPECT_NE(nullptr, method);
    297   EXPECT_FALSE(env_->ExceptionCheck());
    298 
    299   // Check that GetMethodID can find a interface method inherited from another interface.
    300   method = env_->GetMethodID(jncrbc, "close", "()V");
    301   EXPECT_NE(nullptr, method);
    302   EXPECT_FALSE(env_->ExceptionCheck());
    303 
    304   // Bad arguments.
    305   CheckJniAbortCatcher check_jni_abort_catcher;
    306   method = env_->GetMethodID(nullptr, "<init>", "(Ljava/lang/String;)V");
    307   EXPECT_EQ(nullptr, method);
    308   check_jni_abort_catcher.Check("java_class == null");
    309   method = env_->GetMethodID(jlnsme, nullptr, "(Ljava/lang/String;)V");
    310   EXPECT_EQ(nullptr, method);
    311   check_jni_abort_catcher.Check("name == null");
    312   method = env_->GetMethodID(jlnsme, "<init>", nullptr);
    313   EXPECT_EQ(nullptr, method);
    314   check_jni_abort_catcher.Check("sig == null");
    315 }
    316 
    317 TEST_F(JniInternalTest, CallVoidMethodNullReceiver) {
    318   jclass jlobject = env_->FindClass("java/lang/Object");
    319   jmethodID method;
    320 
    321   // Check that GetMethodID for java.lang.NoSuchMethodError.<init>(String) finds the constructor.
    322   method = env_->GetMethodID(jlobject, "<init>", "()V");
    323   EXPECT_NE(nullptr, method);
    324   EXPECT_FALSE(env_->ExceptionCheck());
    325 
    326   // Null object to CallVoidMethod.
    327   CheckJniAbortCatcher check_jni_abort_catcher;
    328   method = env_->GetMethodID(nullptr, "<init>", "(Ljava/lang/String;)V");
    329   env_->CallVoidMethod(nullptr, method);
    330   check_jni_abort_catcher.Check("null");
    331 }
    332 
    333 TEST_F(JniInternalTest, GetStaticMethodID) {
    334   jclass jlobject = env_->FindClass("java/lang/Object");
    335   jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
    336 
    337   // Sanity check that no exceptions are pending
    338   ASSERT_FALSE(env_->ExceptionCheck());
    339 
    340   // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
    341   // a pending exception
    342   jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V");
    343   EXPECT_EQ(nullptr, method);
    344   ExpectException(jlnsme);
    345 
    346   // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as
    347   // the method is not static
    348   method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
    349   EXPECT_EQ(nullptr, method);
    350   ExpectException(jlnsme);
    351 
    352   // Check that java.lang.String.valueOf(int) does exist
    353   jclass jlstring = env_->FindClass("java/lang/String");
    354   method = env_->GetStaticMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
    355   EXPECT_NE(nullptr, method);
    356   EXPECT_FALSE(env_->ExceptionCheck());
    357 
    358   // Bad arguments.
    359   CheckJniAbortCatcher check_jni_abort_catcher;
    360   method = env_->GetStaticMethodID(nullptr, "valueOf", "(I)Ljava/lang/String;");
    361   EXPECT_EQ(nullptr, method);
    362   check_jni_abort_catcher.Check("java_class == null");
    363   method = env_->GetStaticMethodID(jlstring, nullptr, "(I)Ljava/lang/String;");
    364   EXPECT_EQ(nullptr, method);
    365   check_jni_abort_catcher.Check("name == null");
    366   method = env_->GetStaticMethodID(jlstring, "valueOf", nullptr);
    367   EXPECT_EQ(nullptr, method);
    368   check_jni_abort_catcher.Check("sig == null");
    369 }
    370 
    371 TEST_F(JniInternalTest, FromReflectedField_ToReflectedField) {
    372   jclass jlrField = env_->FindClass("java/lang/reflect/Field");
    373   jclass c = env_->FindClass("java/lang/String");
    374   ASSERT_NE(c, nullptr);
    375   jfieldID fid = env_->GetFieldID(c, "count", "I");
    376   ASSERT_NE(fid, nullptr);
    377   // Turn the fid into a java.lang.reflect.Field...
    378   jobject field = env_->ToReflectedField(c, fid, JNI_FALSE);
    379   ASSERT_NE(c, nullptr);
    380   ASSERT_TRUE(env_->IsInstanceOf(field, jlrField));
    381   // ...and back again.
    382   jfieldID fid2 = env_->FromReflectedField(field);
    383   ASSERT_NE(fid2, nullptr);
    384   // Make sure we can actually use it.
    385   jstring s = env_->NewStringUTF("poop");
    386   ASSERT_EQ(4, env_->GetIntField(s, fid2));
    387 
    388   // Bad arguments.
    389   CheckJniAbortCatcher check_jni_abort_catcher;
    390   field = env_->ToReflectedField(c, nullptr, JNI_FALSE);
    391   EXPECT_EQ(field, nullptr);
    392   check_jni_abort_catcher.Check("fid == null");
    393   fid2 = env_->FromReflectedField(nullptr);
    394   ASSERT_EQ(fid2, nullptr);
    395   check_jni_abort_catcher.Check("jlr_field == null");
    396 }
    397 
    398 TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
    399   jclass jlrMethod = env_->FindClass("java/lang/reflect/Method");
    400   ASSERT_NE(jlrMethod, nullptr);
    401   jclass jlrConstructor = env_->FindClass("java/lang/reflect/Constructor");
    402   ASSERT_NE(jlrConstructor, nullptr);
    403   jclass c = env_->FindClass("java/lang/String");
    404   ASSERT_NE(c, nullptr);
    405 
    406   jmethodID mid = env_->GetMethodID(c, "<init>", "()V");
    407   ASSERT_NE(mid, nullptr);
    408   // Turn the mid into a java.lang.reflect.Constructor...
    409   jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
    410   ASSERT_NE(method, nullptr);
    411   ASSERT_TRUE(env_->IsInstanceOf(method, jlrConstructor));
    412   // ...and back again.
    413   jmethodID mid2 = env_->FromReflectedMethod(method);
    414   ASSERT_NE(mid2, nullptr);
    415   // Make sure we can actually use it.
    416   jstring s = reinterpret_cast<jstring>(env_->AllocObject(c));
    417   ASSERT_NE(s, nullptr);
    418   env_->CallVoidMethod(s, mid2);
    419   ASSERT_EQ(JNI_FALSE, env_->ExceptionCheck());
    420 
    421   mid = env_->GetMethodID(c, "length", "()I");
    422   ASSERT_NE(mid, nullptr);
    423   // Turn the mid into a java.lang.reflect.Method...
    424   method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
    425   ASSERT_NE(method, nullptr);
    426   ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod));
    427   // ...and back again.
    428   mid2 = env_->FromReflectedMethod(method);
    429   ASSERT_NE(mid2, nullptr);
    430   // Make sure we can actually use it.
    431   s = env_->NewStringUTF("poop");
    432   ASSERT_NE(s, nullptr);
    433   ASSERT_EQ(4, env_->CallIntMethod(s, mid2));
    434 
    435   // Bad arguments.
    436   CheckJniAbortCatcher check_jni_abort_catcher;
    437   method = env_->ToReflectedMethod(c, nullptr, JNI_FALSE);
    438   EXPECT_EQ(method, nullptr);
    439   check_jni_abort_catcher.Check("mid == null");
    440   mid2 = env_->FromReflectedMethod(method);
    441   ASSERT_EQ(mid2, nullptr);
    442   check_jni_abort_catcher.Check("jlr_method == null");
    443 }
    444 
    445 static void BogusMethod() {
    446   // You can't pass nullptr function pointers to RegisterNatives.
    447 }
    448 
    449 TEST_F(JniInternalTest, RegisterAndUnregisterNatives) {
    450   jclass jlobject = env_->FindClass("java/lang/Object");
    451   jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
    452   void* native_function = reinterpret_cast<void*>(BogusMethod);
    453 
    454   // Sanity check that no exceptions are pending.
    455   ASSERT_FALSE(env_->ExceptionCheck());
    456 
    457   // Check that registering method without name causes a NoSuchMethodError.
    458   {
    459     JNINativeMethod methods[] = { { nullptr, "()V", native_function } };
    460     EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
    461   }
    462   ExpectException(jlnsme);
    463 
    464   // Check that registering method without signature causes a NoSuchMethodError.
    465   {
    466     JNINativeMethod methods[] = { { "notify", nullptr, native_function } };
    467     EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
    468   }
    469   ExpectException(jlnsme);
    470 
    471   // Check that registering method without function causes a NoSuchMethodError.
    472   {
    473     JNINativeMethod methods[] = { { "notify", "()V", nullptr } };
    474     EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
    475   }
    476   ExpectException(jlnsme);
    477 
    478   // Check that registering to a non-existent java.lang.Object.foo() causes a NoSuchMethodError.
    479   {
    480     JNINativeMethod methods[] = { { "foo", "()V", native_function } };
    481     EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
    482   }
    483   ExpectException(jlnsme);
    484 
    485   // Check that registering non-native methods causes a NoSuchMethodError.
    486   {
    487     JNINativeMethod methods[] = { { "equals", "(Ljava/lang/Object;)Z", native_function } };
    488     EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
    489   }
    490   ExpectException(jlnsme);
    491 
    492   // Check that registering native methods is successful.
    493   {
    494     JNINativeMethod methods[] = { { "notify", "()V", native_function } };
    495     EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_OK);
    496   }
    497   EXPECT_FALSE(env_->ExceptionCheck());
    498   EXPECT_EQ(env_->UnregisterNatives(jlobject), JNI_OK);
    499 
    500   // Check that registering no methods isn't a failure.
    501   {
    502     JNINativeMethod methods[] = { };
    503     EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 0), JNI_OK);
    504   }
    505   EXPECT_FALSE(env_->ExceptionCheck());
    506   EXPECT_EQ(env_->UnregisterNatives(jlobject), JNI_OK);
    507 
    508   // Check that registering a -ve number of methods is a failure.
    509   CheckJniAbortCatcher check_jni_abort_catcher;
    510   for (int i = -10; i < 0; ++i) {
    511     JNINativeMethod methods[] = { };
    512     EXPECT_EQ(env_->RegisterNatives(jlobject, methods, i), JNI_ERR);
    513     check_jni_abort_catcher.Check("negative method count: ");
    514   }
    515   EXPECT_FALSE(env_->ExceptionCheck());
    516 
    517   // Passing a class of null is a failure.
    518   {
    519     JNINativeMethod methods[] = { };
    520     EXPECT_EQ(env_->RegisterNatives(nullptr, methods, 0), JNI_ERR);
    521     check_jni_abort_catcher.Check("java_class == null");
    522   }
    523 
    524   // Passing methods as null is a failure.
    525   EXPECT_EQ(env_->RegisterNatives(jlobject, nullptr, 1), JNI_ERR);
    526   check_jni_abort_catcher.Check("methods == null");
    527 
    528   // Unregisters null is a failure.
    529   EXPECT_EQ(env_->UnregisterNatives(nullptr), JNI_ERR);
    530   check_jni_abort_catcher.Check("java_class == null");
    531 
    532   // Unregistering a class with no natives is a warning.
    533   EXPECT_EQ(env_->UnregisterNatives(jlnsme), JNI_OK);
    534 }
    535 
    536 #define EXPECT_PRIMITIVE_ARRAY(new_fn, \
    537                                get_region_fn, \
    538                                set_region_fn, \
    539                                get_elements_fn, \
    540                                release_elements_fn, \
    541                                scalar_type, \
    542                                expected_class_descriptor) \
    543   jsize size = 4; \
    544   \
    545   { \
    546     CheckJniAbortCatcher jni_abort_catcher; \
    547     /* Allocate an negative sized array and check it has the right failure type. */ \
    548     EXPECT_EQ(env_->new_fn(-1), nullptr); \
    549     jni_abort_catcher.Check("negative array length: -1"); \
    550     EXPECT_EQ(env_->new_fn(std::numeric_limits<jint>::min()), nullptr); \
    551     jni_abort_catcher.Check("negative array length: -2147483648"); \
    552     /* Pass the array as null. */ \
    553     EXPECT_EQ(0, env_->GetArrayLength(nullptr)); \
    554     jni_abort_catcher.Check("java_array == null"); \
    555     env_->get_region_fn(nullptr, 0, 0, nullptr); \
    556     jni_abort_catcher.Check("java_array == null"); \
    557     env_->set_region_fn(nullptr, 0, 0, nullptr); \
    558     jni_abort_catcher.Check("java_array == null"); \
    559     env_->get_elements_fn(nullptr, nullptr); \
    560     jni_abort_catcher.Check("java_array == null"); \
    561     env_->release_elements_fn(nullptr, nullptr, 0); \
    562     jni_abort_catcher.Check("java_array == null"); \
    563     /* Pass the elements for region as null. */ \
    564     scalar_type ## Array a = env_->new_fn(size); \
    565     env_->get_region_fn(a, 0, size, nullptr); \
    566     jni_abort_catcher.Check("buf == null"); \
    567     env_->set_region_fn(a, 0, size, nullptr); \
    568     jni_abort_catcher.Check("buf == null"); \
    569   } \
    570   /* Allocate an array and check it has the right type and length. */ \
    571   scalar_type ## Array a = env_->new_fn(size); \
    572   EXPECT_NE(a, nullptr); \
    573   EXPECT_TRUE(env_->IsInstanceOf(a, env_->FindClass(expected_class_descriptor))); \
    574   EXPECT_EQ(size, env_->GetArrayLength(a)); \
    575   \
    576   /* GetPrimitiveArrayRegion/SetPrimitiveArrayRegion */ \
    577   /* AIOOBE for negative start offset. */ \
    578   env_->get_region_fn(a, -1, 1, nullptr); \
    579   ExpectException(aioobe_); \
    580   env_->set_region_fn(a, -1, 1, nullptr); \
    581   ExpectException(aioobe_); \
    582   \
    583   /* AIOOBE for negative length. */ \
    584   env_->get_region_fn(a, 0, -1, nullptr); \
    585   ExpectException(aioobe_); \
    586   env_->set_region_fn(a, 0, -1, nullptr); \
    587   ExpectException(aioobe_); \
    588   \
    589   /* AIOOBE for buffer overrun. */ \
    590   env_->get_region_fn(a, size - 1, size, nullptr); \
    591   ExpectException(aioobe_); \
    592   env_->set_region_fn(a, size - 1, size, nullptr); \
    593   ExpectException(aioobe_); \
    594   \
    595   /* It's okay for the buffer to be nullptr as long as the length is 0. */ \
    596   env_->get_region_fn(a, 2, 0, nullptr); \
    597   /* Even if the offset is invalid... */ \
    598   env_->get_region_fn(a, 123, 0, nullptr); \
    599   ExpectException(aioobe_); \
    600   \
    601   /* It's okay for the buffer to be nullptr as long as the length is 0. */ \
    602   env_->set_region_fn(a, 2, 0, nullptr); \
    603   /* Even if the offset is invalid... */ \
    604   env_->set_region_fn(a, 123, 0, nullptr); \
    605   ExpectException(aioobe_); \
    606   \
    607   /* Prepare a couple of buffers. */ \
    608   std::unique_ptr<scalar_type[]> src_buf(new scalar_type[size]); \
    609   std::unique_ptr<scalar_type[]> dst_buf(new scalar_type[size]); \
    610   for (jsize i = 0; i < size; ++i) { src_buf[i] = scalar_type(i); } \
    611   for (jsize i = 0; i < size; ++i) { dst_buf[i] = scalar_type(-1); } \
    612   \
    613   /* Copy all of src_buf onto the heap. */ \
    614   env_->set_region_fn(a, 0, size, &src_buf[0]); \
    615   /* Copy back only part. */ \
    616   env_->get_region_fn(a, 1, size - 2, &dst_buf[1]); \
    617   EXPECT_NE(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
    618     << "short copy equal"; \
    619   /* Copy the missing pieces. */ \
    620   env_->get_region_fn(a, 0, 1, &dst_buf[0]); \
    621   env_->get_region_fn(a, size - 1, 1, &dst_buf[size - 1]); \
    622   EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
    623     << "fixed copy not equal"; \
    624   /* Copy back the whole array. */ \
    625   env_->get_region_fn(a, 0, size, &dst_buf[0]); \
    626   EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
    627     << "full copy not equal"; \
    628   /* GetPrimitiveArrayCritical */ \
    629   void* v = env_->GetPrimitiveArrayCritical(a, nullptr); \
    630   EXPECT_EQ(memcmp(&src_buf[0], v, size * sizeof(scalar_type)), 0) \
    631     << "GetPrimitiveArrayCritical not equal"; \
    632   env_->ReleasePrimitiveArrayCritical(a, v, 0); \
    633   /* GetXArrayElements */ \
    634   scalar_type* xs = env_->get_elements_fn(a, nullptr); \
    635   EXPECT_EQ(memcmp(&src_buf[0], xs, size * sizeof(scalar_type)), 0) \
    636     << # get_elements_fn " not equal"; \
    637   env_->release_elements_fn(a, xs, 0); \
    638 
    639 TEST_F(JniInternalTest, BooleanArrays) {
    640   EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion,
    641                          GetBooleanArrayElements, ReleaseBooleanArrayElements, jboolean, "[Z");
    642 }
    643 TEST_F(JniInternalTest, ByteArrays) {
    644   EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion,
    645                          GetByteArrayElements, ReleaseByteArrayElements, jbyte, "[B");
    646 }
    647 TEST_F(JniInternalTest, CharArrays) {
    648   EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion,
    649                          GetCharArrayElements, ReleaseCharArrayElements, jchar, "[C");
    650 }
    651 TEST_F(JniInternalTest, DoubleArrays) {
    652   EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion,
    653                          GetDoubleArrayElements, ReleaseDoubleArrayElements, jdouble, "[D");
    654 }
    655 TEST_F(JniInternalTest, FloatArrays) {
    656   EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion,
    657                          GetFloatArrayElements, ReleaseFloatArrayElements, jfloat, "[F");
    658 }
    659 TEST_F(JniInternalTest, IntArrays) {
    660   EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion,
    661                          GetIntArrayElements, ReleaseIntArrayElements, jint, "[I");
    662 }
    663 TEST_F(JniInternalTest, LongArrays) {
    664   EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion,
    665                          GetLongArrayElements, ReleaseLongArrayElements, jlong, "[J");
    666 }
    667 TEST_F(JniInternalTest, ShortArrays) {
    668   EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion,
    669                          GetShortArrayElements, ReleaseShortArrayElements, jshort, "[S");
    670 }
    671 
    672 TEST_F(JniInternalTest, GetPrimitiveArrayElementsOfWrongType) {
    673   CheckJniAbortCatcher jni_abort_catcher;
    674   jbooleanArray array = env_->NewBooleanArray(10);
    675   jboolean is_copy;
    676   EXPECT_EQ(env_->GetByteArrayElements(reinterpret_cast<jbyteArray>(array), &is_copy), nullptr);
    677   jni_abort_catcher.Check(
    678       "attempt to get byte primitive array elements with an object of type boolean[]");
    679   EXPECT_EQ(env_->GetShortArrayElements(reinterpret_cast<jshortArray>(array), &is_copy), nullptr);
    680   jni_abort_catcher.Check(
    681       "attempt to get short primitive array elements with an object of type boolean[]");
    682   EXPECT_EQ(env_->GetCharArrayElements(reinterpret_cast<jcharArray>(array), &is_copy), nullptr);
    683   jni_abort_catcher.Check(
    684       "attempt to get char primitive array elements with an object of type boolean[]");
    685   EXPECT_EQ(env_->GetIntArrayElements(reinterpret_cast<jintArray>(array), &is_copy), nullptr);
    686   jni_abort_catcher.Check(
    687       "attempt to get int primitive array elements with an object of type boolean[]");
    688   EXPECT_EQ(env_->GetLongArrayElements(reinterpret_cast<jlongArray>(array), &is_copy), nullptr);
    689   jni_abort_catcher.Check(
    690       "attempt to get long primitive array elements with an object of type boolean[]");
    691   EXPECT_EQ(env_->GetFloatArrayElements(reinterpret_cast<jfloatArray>(array), &is_copy), nullptr);
    692   jni_abort_catcher.Check(
    693       "attempt to get float primitive array elements with an object of type boolean[]");
    694   EXPECT_EQ(env_->GetDoubleArrayElements(reinterpret_cast<jdoubleArray>(array), &is_copy), nullptr);
    695   jni_abort_catcher.Check(
    696       "attempt to get double primitive array elements with an object of type boolean[]");
    697   jbyteArray array2 = env_->NewByteArray(10);
    698   EXPECT_EQ(env_->GetBooleanArrayElements(reinterpret_cast<jbooleanArray>(array2), &is_copy),
    699             nullptr);
    700   jni_abort_catcher.Check(
    701       "attempt to get boolean primitive array elements with an object of type byte[]");
    702   jobject object = env_->NewStringUTF("Test String");
    703   EXPECT_EQ(env_->GetBooleanArrayElements(reinterpret_cast<jbooleanArray>(object), &is_copy),
    704             nullptr);
    705   jni_abort_catcher.Check(
    706       "attempt to get boolean primitive array elements with an object of type java.lang.String");
    707 }
    708 
    709 TEST_F(JniInternalTest, ReleasePrimitiveArrayElementsOfWrongType) {
    710   CheckJniAbortCatcher jni_abort_catcher;
    711   jbooleanArray array = env_->NewBooleanArray(10);
    712   ASSERT_TRUE(array != nullptr);
    713   jboolean is_copy;
    714   jboolean* elements = env_->GetBooleanArrayElements(array, &is_copy);
    715   ASSERT_TRUE(elements != nullptr);
    716   env_->ReleaseByteArrayElements(reinterpret_cast<jbyteArray>(array),
    717                                  reinterpret_cast<jbyte*>(elements), 0);
    718   jni_abort_catcher.Check(
    719       "attempt to release byte primitive array elements with an object of type boolean[]");
    720   env_->ReleaseShortArrayElements(reinterpret_cast<jshortArray>(array),
    721                                   reinterpret_cast<jshort*>(elements), 0);
    722   jni_abort_catcher.Check(
    723       "attempt to release short primitive array elements with an object of type boolean[]");
    724   env_->ReleaseCharArrayElements(reinterpret_cast<jcharArray>(array),
    725                                  reinterpret_cast<jchar*>(elements), 0);
    726   jni_abort_catcher.Check(
    727       "attempt to release char primitive array elements with an object of type boolean[]");
    728   env_->ReleaseIntArrayElements(reinterpret_cast<jintArray>(array),
    729                                 reinterpret_cast<jint*>(elements), 0);
    730   jni_abort_catcher.Check(
    731       "attempt to release int primitive array elements with an object of type boolean[]");
    732   env_->ReleaseLongArrayElements(reinterpret_cast<jlongArray>(array),
    733                                  reinterpret_cast<jlong*>(elements), 0);
    734   jni_abort_catcher.Check(
    735       "attempt to release long primitive array elements with an object of type boolean[]");
    736   env_->ReleaseFloatArrayElements(reinterpret_cast<jfloatArray>(array),
    737                                   reinterpret_cast<jfloat*>(elements), 0);
    738   jni_abort_catcher.Check(
    739       "attempt to release float primitive array elements with an object of type boolean[]");
    740   env_->ReleaseDoubleArrayElements(reinterpret_cast<jdoubleArray>(array),
    741                                   reinterpret_cast<jdouble*>(elements), 0);
    742   jni_abort_catcher.Check(
    743       "attempt to release double primitive array elements with an object of type boolean[]");
    744   jbyteArray array2 = env_->NewByteArray(10);
    745   env_->ReleaseBooleanArrayElements(reinterpret_cast<jbooleanArray>(array2), elements, 0);
    746   jni_abort_catcher.Check(
    747       "attempt to release boolean primitive array elements with an object of type byte[]");
    748   jobject object = env_->NewStringUTF("Test String");
    749   env_->ReleaseBooleanArrayElements(reinterpret_cast<jbooleanArray>(object), elements, 0);
    750   jni_abort_catcher.Check(
    751       "attempt to release boolean primitive array elements with an object of type "
    752       "java.lang.String");
    753 }
    754 TEST_F(JniInternalTest, GetReleasePrimitiveArrayCriticalOfWrongType) {
    755   CheckJniAbortCatcher jni_abort_catcher;
    756   jobject object = env_->NewStringUTF("Test String");
    757   jboolean is_copy;
    758   void* elements = env_->GetPrimitiveArrayCritical(reinterpret_cast<jarray>(object), &is_copy);
    759   jni_abort_catcher.Check("expected primitive array, given java.lang.String");
    760   env_->ReleasePrimitiveArrayCritical(reinterpret_cast<jarray>(object), elements, 0);
    761   jni_abort_catcher.Check("expected primitive array, given java.lang.String");
    762 }
    763 
    764 TEST_F(JniInternalTest, GetPrimitiveArrayRegionElementsOfWrongType) {
    765   CheckJniAbortCatcher jni_abort_catcher;
    766   constexpr size_t kLength = 10;
    767   jbooleanArray array = env_->NewBooleanArray(kLength);
    768   ASSERT_TRUE(array != nullptr);
    769   jboolean elements[kLength];
    770   env_->GetByteArrayRegion(reinterpret_cast<jbyteArray>(array), 0, kLength,
    771                            reinterpret_cast<jbyte*>(elements));
    772   jni_abort_catcher.Check(
    773       "attempt to get region of byte primitive array elements with an object of type boolean[]");
    774   env_->GetShortArrayRegion(reinterpret_cast<jshortArray>(array), 0, kLength,
    775                             reinterpret_cast<jshort*>(elements));
    776   jni_abort_catcher.Check(
    777       "attempt to get region of short primitive array elements with an object of type boolean[]");
    778   env_->GetCharArrayRegion(reinterpret_cast<jcharArray>(array), 0, kLength,
    779                            reinterpret_cast<jchar*>(elements));
    780   jni_abort_catcher.Check(
    781       "attempt to get region of char primitive array elements with an object of type boolean[]");
    782   env_->GetIntArrayRegion(reinterpret_cast<jintArray>(array), 0, kLength,
    783                           reinterpret_cast<jint*>(elements));
    784   jni_abort_catcher.Check(
    785       "attempt to get region of int primitive array elements with an object of type boolean[]");
    786   env_->GetLongArrayRegion(reinterpret_cast<jlongArray>(array), 0, kLength,
    787                            reinterpret_cast<jlong*>(elements));
    788   jni_abort_catcher.Check(
    789       "attempt to get region of long primitive array elements with an object of type boolean[]");
    790   env_->GetFloatArrayRegion(reinterpret_cast<jfloatArray>(array), 0, kLength,
    791                             reinterpret_cast<jfloat*>(elements));
    792   jni_abort_catcher.Check(
    793       "attempt to get region of float primitive array elements with an object of type boolean[]");
    794   env_->GetDoubleArrayRegion(reinterpret_cast<jdoubleArray>(array), 0, kLength,
    795                            reinterpret_cast<jdouble*>(elements));
    796   jni_abort_catcher.Check(
    797       "attempt to get region of double primitive array elements with an object of type boolean[]");
    798   jbyteArray array2 = env_->NewByteArray(10);
    799   env_->GetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(array2), 0, kLength,
    800                               reinterpret_cast<jboolean*>(elements));
    801   jni_abort_catcher.Check(
    802       "attempt to get region of boolean primitive array elements with an object of type byte[]");
    803   jobject object = env_->NewStringUTF("Test String");
    804   env_->GetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(object), 0, kLength,
    805                               reinterpret_cast<jboolean*>(elements));
    806   jni_abort_catcher.Check(
    807       "attempt to get region of boolean primitive array elements with an object of type "
    808       "java.lang.String");
    809 }
    810 
    811 TEST_F(JniInternalTest, SetPrimitiveArrayRegionElementsOfWrongType) {
    812   CheckJniAbortCatcher jni_abort_catcher;
    813   constexpr size_t kLength = 10;
    814   jbooleanArray array = env_->NewBooleanArray(kLength);
    815   ASSERT_TRUE(array != nullptr);
    816   jboolean elements[kLength];
    817   env_->SetByteArrayRegion(reinterpret_cast<jbyteArray>(array), 0, kLength,
    818                            reinterpret_cast<jbyte*>(elements));
    819   jni_abort_catcher.Check(
    820       "attempt to set region of byte primitive array elements with an object of type boolean[]");
    821   env_->SetShortArrayRegion(reinterpret_cast<jshortArray>(array), 0, kLength,
    822                             reinterpret_cast<jshort*>(elements));
    823   jni_abort_catcher.Check(
    824       "attempt to set region of short primitive array elements with an object of type boolean[]");
    825   env_->SetCharArrayRegion(reinterpret_cast<jcharArray>(array), 0, kLength,
    826                            reinterpret_cast<jchar*>(elements));
    827   jni_abort_catcher.Check(
    828       "attempt to set region of char primitive array elements with an object of type boolean[]");
    829   env_->SetIntArrayRegion(reinterpret_cast<jintArray>(array), 0, kLength,
    830                           reinterpret_cast<jint*>(elements));
    831   jni_abort_catcher.Check(
    832       "attempt to set region of int primitive array elements with an object of type boolean[]");
    833   env_->SetLongArrayRegion(reinterpret_cast<jlongArray>(array), 0, kLength,
    834                            reinterpret_cast<jlong*>(elements));
    835   jni_abort_catcher.Check(
    836       "attempt to set region of long primitive array elements with an object of type boolean[]");
    837   env_->SetFloatArrayRegion(reinterpret_cast<jfloatArray>(array), 0, kLength,
    838                             reinterpret_cast<jfloat*>(elements));
    839   jni_abort_catcher.Check(
    840       "attempt to set region of float primitive array elements with an object of type boolean[]");
    841   env_->SetDoubleArrayRegion(reinterpret_cast<jdoubleArray>(array), 0, kLength,
    842                            reinterpret_cast<jdouble*>(elements));
    843   jni_abort_catcher.Check(
    844       "attempt to set region of double primitive array elements with an object of type boolean[]");
    845   jbyteArray array2 = env_->NewByteArray(10);
    846   env_->SetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(array2), 0, kLength,
    847                               reinterpret_cast<jboolean*>(elements));
    848   jni_abort_catcher.Check(
    849       "attempt to set region of boolean primitive array elements with an object of type byte[]");
    850   jobject object = env_->NewStringUTF("Test String");
    851   env_->SetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(object), 0, kLength,
    852                               reinterpret_cast<jboolean*>(elements));
    853   jni_abort_catcher.Check(
    854       "attempt to set region of boolean primitive array elements with an object of type "
    855       "java.lang.String");
    856 }
    857 
    858 TEST_F(JniInternalTest, NewObjectArray) {
    859   jclass element_class = env_->FindClass("java/lang/String");
    860   ASSERT_NE(element_class, nullptr);
    861   jclass array_class = env_->FindClass("[Ljava/lang/String;");
    862   ASSERT_NE(array_class, nullptr);
    863 
    864   jobjectArray a = env_->NewObjectArray(0, element_class, nullptr);
    865   EXPECT_NE(a, nullptr);
    866   EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
    867   EXPECT_EQ(0, env_->GetArrayLength(a));
    868 
    869   a = env_->NewObjectArray(1, element_class, nullptr);
    870   EXPECT_NE(a, nullptr);
    871   EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
    872   EXPECT_EQ(1, env_->GetArrayLength(a));
    873   EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), nullptr));
    874 
    875   // Negative array length checks.
    876   CheckJniAbortCatcher jni_abort_catcher;
    877   env_->NewObjectArray(-1, element_class, nullptr);
    878   jni_abort_catcher.Check("negative array length: -1");
    879 
    880   env_->NewObjectArray(std::numeric_limits<jint>::min(), element_class, nullptr);
    881   jni_abort_catcher.Check("negative array length: -2147483648");
    882 }
    883 
    884 TEST_F(JniInternalTest, NewObjectArrayWithPrimitiveClasses) {
    885   const char* primitive_descriptors = "VZBSCIJFD";
    886   const char* primitive_names[] = {
    887       "void", "boolean", "byte", "short", "char", "int", "long", "float", "double"
    888   };
    889   ASSERT_EQ(strlen(primitive_descriptors), arraysize(primitive_names));
    890 
    891   CheckJniAbortCatcher jni_abort_catcher;
    892   for (size_t i = 0; i < strlen(primitive_descriptors); ++i) {
    893     env_->NewObjectArray(0, nullptr, nullptr);
    894     jni_abort_catcher.Check("element_jclass == null");
    895     jclass primitive_class = GetPrimitiveClass(primitive_descriptors[i]);
    896     env_->NewObjectArray(1, primitive_class, nullptr);
    897     std::string error_msg(StringPrintf("not an object type: %s", primitive_names[i]));
    898     jni_abort_catcher.Check(error_msg.c_str());
    899   }
    900 }
    901 
    902 TEST_F(JniInternalTest, NewObjectArrayWithInitialValue) {
    903   jclass element_class = env_->FindClass("java/lang/String");
    904   ASSERT_NE(element_class, nullptr);
    905   jclass array_class = env_->FindClass("[Ljava/lang/String;");
    906   ASSERT_NE(array_class, nullptr);
    907 
    908   jstring s = env_->NewStringUTF("poop");
    909   jobjectArray a = env_->NewObjectArray(2, element_class, s);
    910   EXPECT_NE(a, nullptr);
    911   EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
    912   EXPECT_EQ(2, env_->GetArrayLength(a));
    913   EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), s));
    914   EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 1), s));
    915 
    916   // Attempt to incorrect create an array of strings with initial value of string arrays.
    917   CheckJniAbortCatcher jni_abort_catcher;
    918   env_->NewObjectArray(2, element_class, a);
    919   jni_abort_catcher.Check("cannot assign object of type 'java.lang.String[]' to array with element "
    920                           "type of 'java.lang.String'");
    921 }
    922 
    923 TEST_F(JniInternalTest, GetArrayLength) {
    924   // Already tested in NewObjectArray/NewPrimitiveArray.
    925 }
    926 
    927 TEST_F(JniInternalTest, GetObjectClass) {
    928   jclass string_class = env_->FindClass("java/lang/String");
    929   ASSERT_NE(string_class, nullptr);
    930   jclass class_class = env_->FindClass("java/lang/Class");
    931   ASSERT_NE(class_class, nullptr);
    932 
    933   jstring s = env_->NewStringUTF("poop");
    934   jclass c = env_->GetObjectClass(s);
    935   ASSERT_TRUE(env_->IsSameObject(string_class, c));
    936 
    937   jclass c2 = env_->GetObjectClass(c);
    938   ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2)));
    939 
    940   // Null as object should fail.
    941   CheckJniAbortCatcher jni_abort_catcher;
    942   EXPECT_EQ(env_->GetObjectClass(nullptr), nullptr);
    943   jni_abort_catcher.Check("java_object == null");
    944 }
    945 
    946 TEST_F(JniInternalTest, GetSuperclass) {
    947   jclass object_class = env_->FindClass("java/lang/Object");
    948   ASSERT_NE(object_class, nullptr);
    949   jclass string_class = env_->FindClass("java/lang/String");
    950   ASSERT_NE(string_class, nullptr);
    951   jclass runnable_interface = env_->FindClass("java/lang/Runnable");
    952   ASSERT_NE(runnable_interface, nullptr);
    953   ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class)));
    954   ASSERT_EQ(env_->GetSuperclass(object_class), nullptr);
    955   ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(runnable_interface)));
    956 
    957   // Null as class should fail.
    958   CheckJniAbortCatcher jni_abort_catcher;
    959   EXPECT_EQ(env_->GetSuperclass(nullptr), nullptr);
    960   jni_abort_catcher.Check("java_class == null");
    961 }
    962 
    963 TEST_F(JniInternalTest, IsAssignableFrom) {
    964   jclass object_class = env_->FindClass("java/lang/Object");
    965   ASSERT_NE(object_class, nullptr);
    966   jclass string_class = env_->FindClass("java/lang/String");
    967   ASSERT_NE(string_class, nullptr);
    968 
    969   // A superclass is assignable from an instance of its
    970   // subclass but not vice versa.
    971   ASSERT_TRUE(env_->IsAssignableFrom(string_class, object_class));
    972   ASSERT_FALSE(env_->IsAssignableFrom(object_class, string_class));
    973 
    974   jclass charsequence_interface = env_->FindClass("java/lang/CharSequence");
    975   ASSERT_NE(charsequence_interface, nullptr);
    976 
    977   // An interface is assignable from an instance of an implementing
    978   // class but not vice versa.
    979   ASSERT_TRUE(env_->IsAssignableFrom(string_class, charsequence_interface));
    980   ASSERT_FALSE(env_->IsAssignableFrom(charsequence_interface, string_class));
    981 
    982   // Check that arrays are covariant.
    983   jclass string_array_class = env_->FindClass("[Ljava/lang/String;");
    984   ASSERT_NE(string_array_class, nullptr);
    985   jclass object_array_class = env_->FindClass("[Ljava/lang/Object;");
    986   ASSERT_NE(object_array_class, nullptr);
    987   ASSERT_TRUE(env_->IsAssignableFrom(string_array_class, object_array_class));
    988   ASSERT_FALSE(env_->IsAssignableFrom(object_array_class, string_array_class));
    989 
    990   // Primitive types are tested in 004-JniTest.
    991 
    992   // Null as either class should fail.
    993   CheckJniAbortCatcher jni_abort_catcher;
    994   EXPECT_EQ(env_->IsAssignableFrom(nullptr, string_class), JNI_FALSE);
    995   jni_abort_catcher.Check("java_class1 == null");
    996   EXPECT_EQ(env_->IsAssignableFrom(object_class, nullptr), JNI_FALSE);
    997   jni_abort_catcher.Check("java_class2 == null");
    998 }
    999 
   1000 TEST_F(JniInternalTest, GetObjectRefType) {
   1001   jclass local = env_->FindClass("java/lang/Object");
   1002   ASSERT_TRUE(local != nullptr);
   1003   EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(local));
   1004 
   1005   jobject global = env_->NewGlobalRef(local);
   1006   EXPECT_EQ(JNIGlobalRefType, env_->GetObjectRefType(global));
   1007 
   1008   jweak weak_global = env_->NewWeakGlobalRef(local);
   1009   EXPECT_EQ(JNIWeakGlobalRefType, env_->GetObjectRefType(weak_global));
   1010 
   1011   jobject invalid = reinterpret_cast<jobject>(this);
   1012   EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(invalid));
   1013 
   1014   // TODO: invoke a native method and test that its arguments are considered local references.
   1015 
   1016   // Null as object should fail.
   1017   CheckJniAbortCatcher jni_abort_catcher;
   1018   EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(nullptr));
   1019   jni_abort_catcher.Check("java_object == null");
   1020 }
   1021 
   1022 TEST_F(JniInternalTest, StaleWeakGlobal) {
   1023   jclass java_lang_Class = env_->FindClass("java/lang/Class");
   1024   ASSERT_NE(java_lang_Class, nullptr);
   1025   jobjectArray local_ref = env_->NewObjectArray(1, java_lang_Class, nullptr);
   1026   ASSERT_NE(local_ref, nullptr);
   1027   jweak weak_global = env_->NewWeakGlobalRef(local_ref);
   1028   ASSERT_NE(weak_global, nullptr);
   1029   env_->DeleteLocalRef(local_ref);
   1030   Runtime::Current()->GetHeap()->CollectGarbage(false);  // GC should clear the weak global.
   1031   jobject new_global_ref = env_->NewGlobalRef(weak_global);
   1032   EXPECT_EQ(new_global_ref, nullptr);
   1033   jobject new_local_ref = env_->NewLocalRef(weak_global);
   1034   EXPECT_EQ(new_local_ref, nullptr);
   1035 }
   1036 
   1037 TEST_F(JniInternalTest, NewStringUTF) {
   1038   EXPECT_EQ(env_->NewStringUTF(nullptr), nullptr);
   1039   jstring s;
   1040 
   1041   s = env_->NewStringUTF("");
   1042   EXPECT_NE(s, nullptr);
   1043   EXPECT_EQ(0, env_->GetStringLength(s));
   1044   EXPECT_EQ(0, env_->GetStringUTFLength(s));
   1045   s = env_->NewStringUTF("hello");
   1046   EXPECT_NE(s, nullptr);
   1047   EXPECT_EQ(5, env_->GetStringLength(s));
   1048   EXPECT_EQ(5, env_->GetStringUTFLength(s));
   1049 
   1050   // TODO: check some non-ASCII strings.
   1051 }
   1052 
   1053 TEST_F(JniInternalTest, NewString) {
   1054   jchar chars[] = { 'h', 'i' };
   1055   jstring s;
   1056   s = env_->NewString(chars, 0);
   1057   EXPECT_NE(s, nullptr);
   1058   EXPECT_EQ(0, env_->GetStringLength(s));
   1059   EXPECT_EQ(0, env_->GetStringUTFLength(s));
   1060   s = env_->NewString(chars, 2);
   1061   EXPECT_NE(s, nullptr);
   1062   EXPECT_EQ(2, env_->GetStringLength(s));
   1063   EXPECT_EQ(2, env_->GetStringUTFLength(s));
   1064 
   1065   // TODO: check some non-ASCII strings.
   1066 }
   1067 
   1068 TEST_F(JniInternalTest, NewStringNullCharsZeroLength) {
   1069   jstring s = env_->NewString(nullptr, 0);
   1070   EXPECT_NE(s, nullptr);
   1071   EXPECT_EQ(0, env_->GetStringLength(s));
   1072 }
   1073 
   1074 TEST_F(JniInternalTest, NewStringNullCharsNonzeroLength) {
   1075   CheckJniAbortCatcher jni_abort_catcher;
   1076   env_->NewString(nullptr, 1);
   1077   jni_abort_catcher.Check("chars == null && char_count > 0");
   1078 }
   1079 
   1080 TEST_F(JniInternalTest, NewStringNegativeLength) {
   1081   CheckJniAbortCatcher jni_abort_catcher;
   1082   env_->NewString(nullptr, -1);
   1083   jni_abort_catcher.Check("char_count < 0: -1");
   1084   env_->NewString(nullptr, std::numeric_limits<jint>::min());
   1085   jni_abort_catcher.Check("char_count < 0: -2147483648");
   1086 }
   1087 
   1088 TEST_F(JniInternalTest, GetStringLength_GetStringUTFLength) {
   1089   // Already tested in the NewString/NewStringUTF tests.
   1090 }
   1091 
   1092 TEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) {
   1093   jstring s = env_->NewStringUTF("hello");
   1094   ASSERT_TRUE(s != nullptr);
   1095 
   1096   env_->GetStringRegion(s, -1, 0, nullptr);
   1097   ExpectException(sioobe_);
   1098   env_->GetStringRegion(s, 0, -1, nullptr);
   1099   ExpectException(sioobe_);
   1100   env_->GetStringRegion(s, 0, 10, nullptr);
   1101   ExpectException(sioobe_);
   1102   env_->GetStringRegion(s, 10, 1, nullptr);
   1103   ExpectException(sioobe_);
   1104 
   1105   jchar chars[4] = { 'x', 'x', 'x', 'x' };
   1106   env_->GetStringRegion(s, 1, 2, &chars[1]);
   1107   EXPECT_EQ('x', chars[0]);
   1108   EXPECT_EQ('e', chars[1]);
   1109   EXPECT_EQ('l', chars[2]);
   1110   EXPECT_EQ('x', chars[3]);
   1111 
   1112   // It's okay for the buffer to be nullptr as long as the length is 0.
   1113   env_->GetStringRegion(s, 2, 0, nullptr);
   1114   // Even if the offset is invalid...
   1115   env_->GetStringRegion(s, 123, 0, nullptr);
   1116   ExpectException(sioobe_);
   1117 
   1118   env_->GetStringUTFRegion(s, -1, 0, nullptr);
   1119   ExpectException(sioobe_);
   1120   env_->GetStringUTFRegion(s, 0, -1, nullptr);
   1121   ExpectException(sioobe_);
   1122   env_->GetStringUTFRegion(s, 0, 10, nullptr);
   1123   ExpectException(sioobe_);
   1124   env_->GetStringUTFRegion(s, 10, 1, nullptr);
   1125   ExpectException(sioobe_);
   1126 
   1127   char bytes[4] = { 'x', 'x', 'x', 'x' };
   1128   env_->GetStringUTFRegion(s, 1, 2, &bytes[1]);
   1129   EXPECT_EQ('x', bytes[0]);
   1130   EXPECT_EQ('e', bytes[1]);
   1131   EXPECT_EQ('l', bytes[2]);
   1132   EXPECT_EQ('x', bytes[3]);
   1133 
   1134   // It's okay for the buffer to be nullptr as long as the length is 0.
   1135   env_->GetStringUTFRegion(s, 2, 0, nullptr);
   1136   // Even if the offset is invalid...
   1137   env_->GetStringUTFRegion(s, 123, 0, nullptr);
   1138   ExpectException(sioobe_);
   1139 }
   1140 
   1141 TEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) {
   1142   // Passing in a nullptr jstring is ignored normally, but caught by -Xcheck:jni.
   1143   {
   1144     CheckJniAbortCatcher check_jni_abort_catcher;
   1145     EXPECT_EQ(env_->GetStringUTFChars(nullptr, nullptr), nullptr);
   1146     check_jni_abort_catcher.Check("GetStringUTFChars received null jstring");
   1147   }
   1148 
   1149   jstring s = env_->NewStringUTF("hello");
   1150   ASSERT_TRUE(s != nullptr);
   1151 
   1152   const char* utf = env_->GetStringUTFChars(s, nullptr);
   1153   EXPECT_STREQ("hello", utf);
   1154   env_->ReleaseStringUTFChars(s, utf);
   1155 
   1156   jboolean is_copy = JNI_FALSE;
   1157   utf = env_->GetStringUTFChars(s, &is_copy);
   1158   EXPECT_EQ(JNI_TRUE, is_copy);
   1159   EXPECT_STREQ("hello", utf);
   1160   env_->ReleaseStringUTFChars(s, utf);
   1161 }
   1162 
   1163 TEST_F(JniInternalTest, GetStringChars_ReleaseStringChars) {
   1164   jstring s = env_->NewStringUTF("hello");
   1165   ScopedObjectAccess soa(env_);
   1166   mirror::String* s_m = soa.Decode<mirror::String*>(s);
   1167   ASSERT_TRUE(s != nullptr);
   1168 
   1169   jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
   1170   const jchar* chars = env_->GetStringChars(s, nullptr);
   1171   EXPECT_EQ(expected[0], chars[0]);
   1172   EXPECT_EQ(expected[1], chars[1]);
   1173   EXPECT_EQ(expected[2], chars[2]);
   1174   EXPECT_EQ(expected[3], chars[3]);
   1175   EXPECT_EQ(expected[4], chars[4]);
   1176   env_->ReleaseStringChars(s, chars);
   1177 
   1178   jboolean is_copy = JNI_FALSE;
   1179   chars = env_->GetStringChars(s, &is_copy);
   1180   if (Runtime::Current()->GetHeap()->IsMovableObject(s_m->GetCharArray())) {
   1181     EXPECT_EQ(JNI_TRUE, is_copy);
   1182   } else {
   1183     EXPECT_EQ(JNI_FALSE, is_copy);
   1184   }
   1185   EXPECT_EQ(expected[0], chars[0]);
   1186   EXPECT_EQ(expected[1], chars[1]);
   1187   EXPECT_EQ(expected[2], chars[2]);
   1188   EXPECT_EQ(expected[3], chars[3]);
   1189   EXPECT_EQ(expected[4], chars[4]);
   1190   env_->ReleaseStringChars(s, chars);
   1191 }
   1192 
   1193 TEST_F(JniInternalTest, GetStringCritical_ReleaseStringCritical) {
   1194   jstring s = env_->NewStringUTF("hello");
   1195   ASSERT_TRUE(s != nullptr);
   1196 
   1197   jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
   1198   const jchar* chars = env_->GetStringCritical(s, nullptr);
   1199   EXPECT_EQ(expected[0], chars[0]);
   1200   EXPECT_EQ(expected[1], chars[1]);
   1201   EXPECT_EQ(expected[2], chars[2]);
   1202   EXPECT_EQ(expected[3], chars[3]);
   1203   EXPECT_EQ(expected[4], chars[4]);
   1204   env_->ReleaseStringCritical(s, chars);
   1205 
   1206   jboolean is_copy = JNI_TRUE;
   1207   chars = env_->GetStringCritical(s, &is_copy);
   1208   EXPECT_EQ(JNI_FALSE, is_copy);
   1209   EXPECT_EQ(expected[0], chars[0]);
   1210   EXPECT_EQ(expected[1], chars[1]);
   1211   EXPECT_EQ(expected[2], chars[2]);
   1212   EXPECT_EQ(expected[3], chars[3]);
   1213   EXPECT_EQ(expected[4], chars[4]);
   1214   env_->ReleaseStringCritical(s, chars);
   1215 }
   1216 
   1217 TEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) {
   1218   jclass java_lang_Class = env_->FindClass("java/lang/Class");
   1219   ASSERT_TRUE(java_lang_Class != nullptr);
   1220 
   1221   jobjectArray array = env_->NewObjectArray(1, java_lang_Class, nullptr);
   1222   EXPECT_NE(array, nullptr);
   1223   EXPECT_EQ(env_->GetObjectArrayElement(array, 0), nullptr);
   1224   env_->SetObjectArrayElement(array, 0, java_lang_Class);
   1225   EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), java_lang_Class));
   1226 
   1227   // ArrayIndexOutOfBounds for negative index.
   1228   env_->SetObjectArrayElement(array, -1, java_lang_Class);
   1229   ExpectException(aioobe_);
   1230 
   1231   // ArrayIndexOutOfBounds for too-large index.
   1232   env_->SetObjectArrayElement(array, 1, java_lang_Class);
   1233   ExpectException(aioobe_);
   1234 
   1235   // ArrayStoreException thrown for bad types.
   1236   env_->SetObjectArrayElement(array, 0, env_->NewStringUTF("not a jclass!"));
   1237   ExpectException(ase_);
   1238 
   1239   // Null as array should fail.
   1240   CheckJniAbortCatcher jni_abort_catcher;
   1241   EXPECT_EQ(nullptr, env_->GetObjectArrayElement(nullptr, 0));
   1242   jni_abort_catcher.Check("java_array == null");
   1243   env_->SetObjectArrayElement(nullptr, 0, nullptr);
   1244   jni_abort_catcher.Check("java_array == null");
   1245 }
   1246 
   1247 #define EXPECT_STATIC_PRIMITIVE_FIELD(type, field_name, sig, value1, value2) \
   1248   do { \
   1249     jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \
   1250     EXPECT_NE(fid, nullptr); \
   1251     env_->SetStatic ## type ## Field(c, fid, value1); \
   1252     EXPECT_EQ(value1, env_->GetStatic ## type ## Field(c, fid)); \
   1253     env_->SetStatic ## type ## Field(c, fid, value2); \
   1254     EXPECT_EQ(value2, env_->GetStatic ## type ## Field(c, fid)); \
   1255     \
   1256     CheckJniAbortCatcher jni_abort_catcher; \
   1257     env_->GetStatic ## type ## Field(nullptr, fid); \
   1258     jni_abort_catcher.Check("received null jclass"); \
   1259     env_->SetStatic ## type ## Field(nullptr, fid, value1); \
   1260     jni_abort_catcher.Check("received null jclass"); \
   1261     env_->GetStatic ## type ## Field(c, nullptr); \
   1262     jni_abort_catcher.Check("fid == null"); \
   1263     env_->SetStatic ## type ## Field(c, nullptr, value1); \
   1264     jni_abort_catcher.Check("fid == null"); \
   1265   } while (false)
   1266 
   1267 #define EXPECT_PRIMITIVE_FIELD(instance, type, field_name, sig, value1, value2) \
   1268   do { \
   1269     jfieldID fid = env_->GetFieldID(c, field_name, sig); \
   1270     EXPECT_NE(fid, nullptr); \
   1271     env_->Set ## type ## Field(instance, fid, value1); \
   1272     EXPECT_EQ(value1, env_->Get ## type ## Field(instance, fid)); \
   1273     env_->Set ## type ## Field(instance, fid, value2); \
   1274     EXPECT_EQ(value2, env_->Get ## type ## Field(instance, fid)); \
   1275     \
   1276     CheckJniAbortCatcher jni_abort_catcher; \
   1277     env_->Get ## type ## Field(nullptr, fid); \
   1278     jni_abort_catcher.Check("obj == null"); \
   1279     env_->Set ## type ## Field(nullptr, fid, value1); \
   1280     jni_abort_catcher.Check("obj == null"); \
   1281     env_->Get ## type ## Field(instance, nullptr); \
   1282     jni_abort_catcher.Check("fid == null"); \
   1283     env_->Set ## type ## Field(instance, nullptr, value1); \
   1284     jni_abort_catcher.Check("fid == null"); \
   1285   } while (false)
   1286 
   1287 
   1288 TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) {
   1289   TEST_DISABLED_FOR_PORTABLE();
   1290   Thread::Current()->TransitionFromSuspendedToRunnable();
   1291   LoadDex("AllFields");
   1292   bool started = runtime_->Start();
   1293   ASSERT_TRUE(started);
   1294 
   1295   jclass c = env_->FindClass("AllFields");
   1296   ASSERT_NE(c, nullptr);
   1297   jobject o = env_->AllocObject(c);
   1298   ASSERT_NE(o, nullptr);
   1299 
   1300   EXPECT_STATIC_PRIMITIVE_FIELD(Boolean, "sZ", "Z", JNI_TRUE, JNI_FALSE);
   1301   EXPECT_STATIC_PRIMITIVE_FIELD(Byte, "sB", "B", 1, 2);
   1302   EXPECT_STATIC_PRIMITIVE_FIELD(Char, "sC", "C", 'a', 'b');
   1303   EXPECT_STATIC_PRIMITIVE_FIELD(Double, "sD", "D", 1.0, 2.0);
   1304   EXPECT_STATIC_PRIMITIVE_FIELD(Float, "sF", "F", 1.0, 2.0);
   1305   EXPECT_STATIC_PRIMITIVE_FIELD(Int, "sI", "I", 1, 2);
   1306   EXPECT_STATIC_PRIMITIVE_FIELD(Long, "sJ", "J", 1, 2);
   1307   EXPECT_STATIC_PRIMITIVE_FIELD(Short, "sS", "S", 1, 2);
   1308 
   1309   EXPECT_PRIMITIVE_FIELD(o, Boolean, "iZ", "Z", JNI_TRUE, JNI_FALSE);
   1310   EXPECT_PRIMITIVE_FIELD(o, Byte, "iB", "B", 1, 2);
   1311   EXPECT_PRIMITIVE_FIELD(o, Char, "iC", "C", 'a', 'b');
   1312   EXPECT_PRIMITIVE_FIELD(o, Double, "iD", "D", 1.0, 2.0);
   1313   EXPECT_PRIMITIVE_FIELD(o, Float, "iF", "F", 1.0, 2.0);
   1314   EXPECT_PRIMITIVE_FIELD(o, Int, "iI", "I", 1, 2);
   1315   EXPECT_PRIMITIVE_FIELD(o, Long, "iJ", "J", 1, 2);
   1316   EXPECT_PRIMITIVE_FIELD(o, Short, "iS", "S", 1, 2);
   1317 }
   1318 
   1319 TEST_F(JniInternalTest, GetObjectField_SetObjectField) {
   1320   TEST_DISABLED_FOR_PORTABLE();
   1321   Thread::Current()->TransitionFromSuspendedToRunnable();
   1322   LoadDex("AllFields");
   1323   runtime_->Start();
   1324 
   1325   jclass c = env_->FindClass("AllFields");
   1326   ASSERT_NE(c, nullptr);
   1327   jobject o = env_->AllocObject(c);
   1328   ASSERT_NE(o, nullptr);
   1329 
   1330   jstring s1 = env_->NewStringUTF("hello");
   1331   ASSERT_NE(s1, nullptr);
   1332   jstring s2 = env_->NewStringUTF("world");
   1333   ASSERT_NE(s2, nullptr);
   1334 
   1335   jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;");
   1336   ASSERT_NE(s_fid, nullptr);
   1337   jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;");
   1338   ASSERT_NE(i_fid, nullptr);
   1339 
   1340   env_->SetStaticObjectField(c, s_fid, s1);
   1341   ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid)));
   1342   env_->SetStaticObjectField(c, s_fid, s2);
   1343   ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid)));
   1344 
   1345   env_->SetObjectField(o, i_fid, s1);
   1346   ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid)));
   1347   env_->SetObjectField(o, i_fid, s2);
   1348   ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid)));
   1349 }
   1350 
   1351 TEST_F(JniInternalTest, NewLocalRef_nullptr) {
   1352   EXPECT_EQ(env_->NewLocalRef(nullptr), nullptr);
   1353 }
   1354 
   1355 TEST_F(JniInternalTest, NewLocalRef) {
   1356   jstring s = env_->NewStringUTF("");
   1357   ASSERT_NE(s, nullptr);
   1358   jobject o = env_->NewLocalRef(s);
   1359   EXPECT_NE(o, nullptr);
   1360   EXPECT_NE(o, s);
   1361 
   1362   EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(o));
   1363 }
   1364 
   1365 TEST_F(JniInternalTest, DeleteLocalRef_nullptr) {
   1366   env_->DeleteLocalRef(nullptr);
   1367 }
   1368 
   1369 TEST_F(JniInternalTest, DeleteLocalRef) {
   1370   jstring s = env_->NewStringUTF("");
   1371   ASSERT_NE(s, nullptr);
   1372   env_->DeleteLocalRef(s);
   1373 
   1374   // Currently, deleting an already-deleted reference is just a CheckJNI warning.
   1375   {
   1376     CheckJniAbortCatcher check_jni_abort_catcher;
   1377     env_->DeleteLocalRef(s);
   1378 
   1379     std::string expected(StringPrintf("native code passing in reference to "
   1380                                       "invalid local reference: %p", s));
   1381     check_jni_abort_catcher.Check(expected.c_str());
   1382   }
   1383 
   1384   s = env_->NewStringUTF("");
   1385   ASSERT_NE(s, nullptr);
   1386   jobject o = env_->NewLocalRef(s);
   1387   ASSERT_NE(o, nullptr);
   1388 
   1389   env_->DeleteLocalRef(s);
   1390   env_->DeleteLocalRef(o);
   1391 }
   1392 
   1393 TEST_F(JniInternalTest, PushLocalFrame_10395422) {
   1394   // The JNI specification is ambiguous about whether the given capacity is to be interpreted as a
   1395   // maximum or as a minimum, but it seems like it's supposed to be a minimum, and that's how
   1396   // Android historically treated it, and it's how the RI treats it. It's also the more useful
   1397   // interpretation!
   1398   ASSERT_EQ(JNI_OK, env_->PushLocalFrame(0));
   1399   env_->PopLocalFrame(nullptr);
   1400 
   1401   // Negative capacities are not allowed.
   1402   ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(-1));
   1403 
   1404   // And it's okay to have an upper limit. Ours is currently 512.
   1405   ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(8192));
   1406 }
   1407 
   1408 TEST_F(JniInternalTest, PushLocalFrame_PopLocalFrame) {
   1409   jobject original = env_->NewStringUTF("");
   1410   ASSERT_NE(original, nullptr);
   1411 
   1412   jobject outer;
   1413   jobject inner1, inner2;
   1414   ScopedObjectAccess soa(env_);
   1415   mirror::Object* inner2_direct_pointer;
   1416   {
   1417     ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
   1418     outer = env_->NewLocalRef(original);
   1419 
   1420     {
   1421       ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
   1422       inner1 = env_->NewLocalRef(outer);
   1423       inner2 = env_->NewStringUTF("survivor");
   1424       inner2_direct_pointer = soa.Decode<mirror::Object*>(inner2);
   1425       env_->PopLocalFrame(inner2);
   1426     }
   1427 
   1428     EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
   1429     EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(outer));
   1430     EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
   1431 
   1432     // Our local reference for the survivor is invalid because the survivor
   1433     // gets a new local reference...
   1434     EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
   1435 
   1436     env_->PopLocalFrame(nullptr);
   1437   }
   1438   EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
   1439   EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(outer));
   1440   EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
   1441   EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
   1442 }
   1443 
   1444 TEST_F(JniInternalTest, NewGlobalRef_nullptr) {
   1445   EXPECT_EQ(env_->NewGlobalRef(nullptr), nullptr);
   1446 }
   1447 
   1448 TEST_F(JniInternalTest, NewGlobalRef) {
   1449   jstring s = env_->NewStringUTF("");
   1450   ASSERT_NE(s, nullptr);
   1451   jobject o = env_->NewGlobalRef(s);
   1452   EXPECT_NE(o, nullptr);
   1453   EXPECT_NE(o, s);
   1454 
   1455   EXPECT_EQ(env_->GetObjectRefType(o), JNIGlobalRefType);
   1456 }
   1457 
   1458 TEST_F(JniInternalTest, DeleteGlobalRef_nullptr) {
   1459   env_->DeleteGlobalRef(nullptr);
   1460 }
   1461 
   1462 TEST_F(JniInternalTest, DeleteGlobalRef) {
   1463   jstring s = env_->NewStringUTF("");
   1464   ASSERT_NE(s, nullptr);
   1465 
   1466   jobject o = env_->NewGlobalRef(s);
   1467   ASSERT_NE(o, nullptr);
   1468   env_->DeleteGlobalRef(o);
   1469 
   1470   // Currently, deleting an already-deleted reference is just a CheckJNI warning.
   1471   {
   1472     CheckJniAbortCatcher check_jni_abort_catcher;
   1473     env_->DeleteGlobalRef(o);
   1474 
   1475     std::string expected(StringPrintf("native code passing in reference to "
   1476                                       "invalid global reference: %p", o));
   1477     check_jni_abort_catcher.Check(expected.c_str());
   1478   }
   1479 
   1480   jobject o1 = env_->NewGlobalRef(s);
   1481   ASSERT_NE(o1, nullptr);
   1482   jobject o2 = env_->NewGlobalRef(s);
   1483   ASSERT_NE(o2, nullptr);
   1484 
   1485   env_->DeleteGlobalRef(o1);
   1486   env_->DeleteGlobalRef(o2);
   1487 }
   1488 
   1489 TEST_F(JniInternalTest, NewWeakGlobalRef_nullptr) {
   1490   EXPECT_EQ(env_->NewWeakGlobalRef(nullptr),   nullptr);
   1491 }
   1492 
   1493 TEST_F(JniInternalTest, NewWeakGlobalRef) {
   1494   jstring s = env_->NewStringUTF("");
   1495   ASSERT_NE(s, nullptr);
   1496   jobject o = env_->NewWeakGlobalRef(s);
   1497   EXPECT_NE(o, nullptr);
   1498   EXPECT_NE(o, s);
   1499 
   1500   EXPECT_EQ(env_->GetObjectRefType(o), JNIWeakGlobalRefType);
   1501 }
   1502 
   1503 TEST_F(JniInternalTest, DeleteWeakGlobalRef_nullptr) {
   1504   env_->DeleteWeakGlobalRef(nullptr);
   1505 }
   1506 
   1507 TEST_F(JniInternalTest, DeleteWeakGlobalRef) {
   1508   jstring s = env_->NewStringUTF("");
   1509   ASSERT_NE(s, nullptr);
   1510 
   1511   jobject o = env_->NewWeakGlobalRef(s);
   1512   ASSERT_NE(o, nullptr);
   1513   env_->DeleteWeakGlobalRef(o);
   1514 
   1515   // Currently, deleting an already-deleted reference is just a CheckJNI warning.
   1516   {
   1517     CheckJniAbortCatcher check_jni_abort_catcher;
   1518     env_->DeleteWeakGlobalRef(o);
   1519 
   1520     std::string expected(StringPrintf("native code passing in reference to "
   1521                                       "invalid weak global reference: %p", o));
   1522     check_jni_abort_catcher.Check(expected.c_str());
   1523   }
   1524 
   1525   jobject o1 = env_->NewWeakGlobalRef(s);
   1526   ASSERT_NE(o1, nullptr);
   1527   jobject o2 = env_->NewWeakGlobalRef(s);
   1528   ASSERT_NE(o2, nullptr);
   1529 
   1530   env_->DeleteWeakGlobalRef(o1);
   1531   env_->DeleteWeakGlobalRef(o2);
   1532 }
   1533 
   1534 TEST_F(JniInternalTest, ExceptionDescribe) {
   1535   // This checks how ExceptionDescribe handles call without exception.
   1536   env_->ExceptionClear();
   1537   env_->ExceptionDescribe();
   1538 }
   1539 
   1540 TEST_F(JniInternalTest, Throw) {
   1541   EXPECT_EQ(JNI_ERR, env_->Throw(nullptr));
   1542 
   1543   jclass exception_class = env_->FindClass("java/lang/RuntimeException");
   1544   ASSERT_TRUE(exception_class != nullptr);
   1545   jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class));
   1546   ASSERT_TRUE(exception != nullptr);
   1547 
   1548   EXPECT_EQ(JNI_OK, env_->Throw(exception));
   1549   EXPECT_TRUE(env_->ExceptionCheck());
   1550   jthrowable thrown_exception = env_->ExceptionOccurred();
   1551   env_->ExceptionClear();
   1552   EXPECT_TRUE(env_->IsSameObject(exception, thrown_exception));
   1553 }
   1554 
   1555 TEST_F(JniInternalTest, ThrowNew) {
   1556   EXPECT_EQ(JNI_ERR, env_->Throw(nullptr));
   1557 
   1558   jclass exception_class = env_->FindClass("java/lang/RuntimeException");
   1559   ASSERT_TRUE(exception_class != nullptr);
   1560 
   1561   jthrowable thrown_exception;
   1562 
   1563   EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
   1564   EXPECT_TRUE(env_->ExceptionCheck());
   1565   thrown_exception = env_->ExceptionOccurred();
   1566   env_->ExceptionClear();
   1567   EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
   1568 
   1569   EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, nullptr));
   1570   EXPECT_TRUE(env_->ExceptionCheck());
   1571   thrown_exception = env_->ExceptionOccurred();
   1572   env_->ExceptionClear();
   1573   EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
   1574 }
   1575 
   1576 TEST_F(JniInternalTest, NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) {
   1577   // Start runtime.
   1578   Thread* self = Thread::Current();
   1579   self->TransitionFromSuspendedToRunnable();
   1580   MakeExecutable(nullptr, "java.lang.Class");
   1581   MakeExecutable(nullptr, "java.lang.Object");
   1582   MakeExecutable(nullptr, "java.nio.DirectByteBuffer");
   1583   MakeExecutable(nullptr, "java.nio.MemoryBlock");
   1584   MakeExecutable(nullptr, "java.nio.MemoryBlock$UnmanagedBlock");
   1585   MakeExecutable(nullptr, "java.nio.MappedByteBuffer");
   1586   MakeExecutable(nullptr, "java.nio.ByteBuffer");
   1587   MakeExecutable(nullptr, "java.nio.Buffer");
   1588   // TODO: we only load a dex file here as starting the runtime relies upon it.
   1589   const char* class_name = "StaticLeafMethods";
   1590   LoadDex(class_name);
   1591   bool started = runtime_->Start();
   1592   ASSERT_TRUE(started);
   1593 
   1594   jclass buffer_class = env_->FindClass("java/nio/Buffer");
   1595   ASSERT_NE(buffer_class, nullptr);
   1596 
   1597   char bytes[1024];
   1598   jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes));
   1599   ASSERT_NE(buffer, nullptr);
   1600   ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class));
   1601   ASSERT_EQ(env_->GetDirectBufferAddress(buffer), bytes);
   1602   ASSERT_EQ(env_->GetDirectBufferCapacity(buffer), static_cast<jlong>(sizeof(bytes)));
   1603 
   1604   {
   1605     CheckJniAbortCatcher check_jni_abort_catcher;
   1606     env_->NewDirectByteBuffer(bytes, static_cast<jlong>(INT_MAX) + 1);
   1607     check_jni_abort_catcher.Check("in call to NewDirectByteBuffer");
   1608   }
   1609 }
   1610 
   1611 TEST_F(JniInternalTest, MonitorEnterExit) {
   1612   // Create an object to torture.
   1613   jclass object_class = env_->FindClass("java/lang/Object");
   1614   ASSERT_NE(object_class, nullptr);
   1615   jobject object = env_->AllocObject(object_class);
   1616   ASSERT_NE(object, nullptr);
   1617 
   1618   // Expected class of exceptions
   1619   jclass imse_class = env_->FindClass("java/lang/IllegalMonitorStateException");
   1620   ASSERT_NE(imse_class, nullptr);
   1621 
   1622   jthrowable thrown_exception;
   1623 
   1624   // Unlock of unowned monitor
   1625   env_->MonitorExit(object);
   1626   EXPECT_TRUE(env_->ExceptionCheck());
   1627   thrown_exception = env_->ExceptionOccurred();
   1628   env_->ExceptionClear();
   1629   EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
   1630 
   1631   // Lock of unowned monitor
   1632   env_->MonitorEnter(object);
   1633   EXPECT_FALSE(env_->ExceptionCheck());
   1634   // Regular unlock
   1635   env_->MonitorExit(object);
   1636   EXPECT_FALSE(env_->ExceptionCheck());
   1637 
   1638   // Recursively lock a lot
   1639   size_t max_recursive_lock = 1024;
   1640   for (size_t i = 0; i < max_recursive_lock; i++) {
   1641     env_->MonitorEnter(object);
   1642     EXPECT_FALSE(env_->ExceptionCheck());
   1643   }
   1644   // Recursively unlock a lot
   1645   for (size_t i = 0; i < max_recursive_lock; i++) {
   1646     env_->MonitorExit(object);
   1647     EXPECT_FALSE(env_->ExceptionCheck());
   1648   }
   1649 
   1650   // Unlock of unowned monitor
   1651   env_->MonitorExit(object);
   1652   EXPECT_TRUE(env_->ExceptionCheck());
   1653   thrown_exception = env_->ExceptionOccurred();
   1654   env_->ExceptionClear();
   1655   EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
   1656 
   1657   // It's an error to call MonitorEnter or MonitorExit on nullptr.
   1658   {
   1659     CheckJniAbortCatcher check_jni_abort_catcher;
   1660     env_->MonitorEnter(nullptr);
   1661     check_jni_abort_catcher.Check("in call to MonitorEnter");
   1662     env_->MonitorExit(nullptr);
   1663     check_jni_abort_catcher.Check("in call to MonitorExit");
   1664   }
   1665 }
   1666 
   1667 TEST_F(JniInternalTest, DetachCurrentThread) {
   1668   CleanUpJniEnv();  // cleanup now so TearDown won't have junk from wrong JNIEnv
   1669   jint ok = vm_->DetachCurrentThread();
   1670   EXPECT_EQ(JNI_OK, ok);
   1671 
   1672   jint err = vm_->DetachCurrentThread();
   1673   EXPECT_EQ(JNI_ERR, err);
   1674   vm_->AttachCurrentThread(&env_, nullptr);  // need attached thread for CommonRuntimeTest::TearDown
   1675 }
   1676 
   1677 }  // namespace art
   1678