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