jni_internal_test.cc revision 85a93364e5111dc56a73eed0130856e66cab0802
12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/*
22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project
32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License.
62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at
72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software
112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and
142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License.
152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */
160c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes
179b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro#include "jni_internal.h"
189b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro
19a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom#include "common_compiler_test.h"
20ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#include "mirror/art_method-inl.h"
2156890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih#include "mirror/string-inl.h"
22726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes#include "ScopedLocalRef.h"
230c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes
240c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughesnamespace art {
250c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes
26a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom// TODO: Convert to CommonRuntimeTest. Currently MakeExecutable is used.
27a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromclass JniInternalTest : public CommonCompilerTest {
28c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott Hughes protected:
29c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott Hughes  virtual void SetUp() {
30a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    CommonCompilerTest::SetUp();
315174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
32a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes    vm_ = Runtime::Current()->GetJavaVM();
33a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes
345174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes    // Turn on -verbose:jni for the JNI tests.
35797136386d6c66289ba1d12cbf5b2ac32646bb90Ian Rogers    // gLogVerbosity.jni = true;
365174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    vm_->AttachCurrentThread(&env_, nullptr);
38b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
39ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    ScopedLocalRef<jclass> aioobe(env_,
40ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                                  env_->FindClass("java/lang/ArrayIndexOutOfBoundsException"));
412d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK(aioobe.get() != nullptr);
42726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes    aioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(aioobe.get()));
43b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
44b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    ScopedLocalRef<jclass> ase(env_, env_->FindClass("java/lang/ArrayStoreException"));
452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK(ase.get() != nullptr);
46b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    ase_ = reinterpret_cast<jclass>(env_->NewGlobalRef(ase.get()));
47b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
48ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    ScopedLocalRef<jclass> sioobe(env_,
49ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                                  env_->FindClass("java/lang/StringIndexOutOfBoundsException"));
502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK(sioobe.get() != nullptr);
51726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes    sioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(sioobe.get()));
52726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes  }
53726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes
542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  void ExpectException(jclass exception_class) {
552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_TRUE(env_->ExceptionCheck());
562d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jthrowable exception = env_->ExceptionOccurred();
572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_NE(nullptr, exception);
582d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->ExceptionClear();
592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class));
602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  }
612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
622d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  void ExpectClassFound(const char* name) {
632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_NE(env_->FindClass(name), nullptr) << name;
642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_FALSE(env_->ExceptionCheck()) << name;
652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  }
662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
672d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  void ExpectClassNotFound(const char* name) {
682d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->FindClass(name), nullptr) << name;
692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_TRUE(env_->ExceptionCheck()) << name;
702d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->ExceptionClear();
712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  }
722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
734d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom  void CleanUpJniEnv() {
742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (aioobe_ != nullptr) {
754d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom      env_->DeleteGlobalRef(aioobe_);
762d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      aioobe_ = nullptr;
774d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom    }
782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (ase_ != nullptr) {
794d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom      env_->DeleteGlobalRef(ase_);
802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      ase_ = nullptr;
814d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom    }
822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (sioobe_ != nullptr) {
834d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom      env_->DeleteGlobalRef(sioobe_);
842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      sioobe_ = nullptr;
854d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom    }
864d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom  }
874d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom
8853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers  virtual void TearDown() OVERRIDE {
894d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom    CleanUpJniEnv();
90a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    CommonCompilerTest::TearDown();
91c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott Hughes  }
92b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
931d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jclass GetPrimitiveClass(char descriptor) {
941d99e4549309d05007d041d058b1878de88e9585Ian Rogers    ScopedObjectAccess soa(env_);
951d99e4549309d05007d041d058b1878de88e9585Ian Rogers    mirror::Class* c = class_linker_->FindPrimitiveClass(descriptor);
961d99e4549309d05007d041d058b1878de88e9585Ian Rogers    CHECK(c != nullptr);
971d99e4549309d05007d041d058b1878de88e9585Ian Rogers    return soa.AddLocalReference<jclass>(c);
981d99e4549309d05007d041d058b1878de88e9585Ian Rogers  }
991d99e4549309d05007d041d058b1878de88e9585Ian Rogers
100a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes  JavaVMExt* vm_;
1014d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom  JNIEnv* env_;
102814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  jclass aioobe_;
103b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  jclass ase_;
104b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jclass sioobe_;
1050c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes};
1060c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes
107885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott HughesTEST_F(JniInternalTest, AllocObject) {
108885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jclass c = env_->FindClass("java/lang/String");
1092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
110885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jobject o = env_->AllocObject(c);
1112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
112885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
113885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  // We have an instance of the class we asked for...
114885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsInstanceOf(o, c));
115885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  // ...whose fields haven't been initialized because
116885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  // we didn't call a constructor.
117885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "count", "I")));
118885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "offset", "I")));
1192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(env_->GetObjectField(o, env_->GetFieldID(c, "value", "[C")) == nullptr);
120885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes}
121885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
122c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott HughesTEST_F(JniInternalTest, GetVersion) {
123c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott Hughes  ASSERT_EQ(JNI_VERSION_1_6, env_->GetVersion());
124c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott Hughes}
125c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott Hughes
1260c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott HughesTEST_F(JniInternalTest, FindClass) {
1270c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes  // Reference types...
1282d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectClassFound("java/lang/String");
1290c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes  // ...for arrays too, where you must include "L;".
1302d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectClassFound("[Ljava/lang/String;");
1313f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes  // Primitive arrays are okay too, if the primitive type is valid.
1322d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectClassFound("[C");
133a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes
134b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  {
1353f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes    CheckJniAbortCatcher check_jni_abort_catcher;
1362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->FindClass(nullptr);
1372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    check_jni_abort_catcher.Check("name == null");
1382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
1392d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    // We support . as well as / for compatibility, if -Xcheck:jni is off.
1402d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ExpectClassFound("java.lang.String");
14156ef042065ce282f8f01a0f31f5cce868a60ede8Elliott Hughes    check_jni_abort_catcher.Check("illegal class name 'java.lang.String'");
1422d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ExpectClassNotFound("Ljava.lang.String;");
14356ef042065ce282f8f01a0f31f5cce868a60ede8Elliott Hughes    check_jni_abort_catcher.Check("illegal class name 'Ljava.lang.String;'");
1442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ExpectClassFound("[Ljava.lang.String;");
14556ef042065ce282f8f01a0f31f5cce868a60ede8Elliott Hughes    check_jni_abort_catcher.Check("illegal class name '[Ljava.lang.String;'");
1462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ExpectClassNotFound("[java.lang.String");
14756ef042065ce282f8f01a0f31f5cce868a60ede8Elliott Hughes    check_jni_abort_catcher.Check("illegal class name '[java.lang.String'");
148b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
149b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    // You can't include the "L;" in a JNI class descriptor.
1502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ExpectClassNotFound("Ljava/lang/String;");
15156ef042065ce282f8f01a0f31f5cce868a60ede8Elliott Hughes    check_jni_abort_catcher.Check("illegal class name 'Ljava/lang/String;'");
1523f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes
153b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    // But you must include it for an array of any reference type.
1542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ExpectClassNotFound("[java/lang/String");
15556ef042065ce282f8f01a0f31f5cce868a60ede8Elliott Hughes    check_jni_abort_catcher.Check("illegal class name '[java/lang/String'");
156a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes
1572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ExpectClassNotFound("[K");
15856ef042065ce282f8f01a0f31f5cce868a60ede8Elliott Hughes    check_jni_abort_catcher.Check("illegal class name '[K'");
1592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
1602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    // Void arrays aren't allowed.
1612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ExpectClassNotFound("[V");
1622d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    check_jni_abort_catcher.Check("illegal class name '[V'");
163b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
1643f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes
1650c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes  // But primitive types aren't allowed...
1662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectClassNotFound("C");
1672d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectClassNotFound("V");
1682d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectClassNotFound("K");
1690c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes}
1700c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes
171cdf53120cd5a73cbedc1654e22542848468c0d2fElliott HughesTEST_F(JniInternalTest, GetFieldID) {
172cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
1732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(jlnsfe, nullptr);
174cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass c = env_->FindClass("java/lang/String");
1752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
176cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
177cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Wrong type.
178cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jfieldID fid = env_->GetFieldID(c, "count", "J");
1792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
1802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
181cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
182b17d08b6ef0d36038e408dd79960293bb62ec1d9Ian Rogers  // Wrong type where type doesn't exist.
183b17d08b6ef0d36038e408dd79960293bb62ec1d9Ian Rogers  fid = env_->GetFieldID(c, "count", "Lrod/jane/freddy;");
1842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
1852d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
186b17d08b6ef0d36038e408dd79960293bb62ec1d9Ian Rogers
187cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Wrong name.
188cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetFieldID(c, "Count", "I");
1892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
1902d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
191cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
192cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Good declared field lookup.
193cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetFieldID(c, "count", "I");
1942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(nullptr, fid);
195cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  EXPECT_FALSE(env_->ExceptionCheck());
196cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
197cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Good superclass field lookup.
198cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  c = env_->FindClass("java/lang/StringBuilder");
199cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetFieldID(c, "count", "I");
2002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(nullptr, fid);
2012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(fid, nullptr);
202cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  EXPECT_FALSE(env_->ExceptionCheck());
203cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
204cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Not instance.
205cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
2062d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
2072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
2082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
2092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Bad arguments.
2102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher check_jni_abort_catcher;
2112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  fid = env_->GetFieldID(nullptr, "count", "I");
2122d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
2132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  check_jni_abort_catcher.Check("java_class == null");
2142d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  fid = env_->GetFieldID(c, nullptr, "I");
2152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
2162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  check_jni_abort_catcher.Check("name == null");
2172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  fid = env_->GetFieldID(c, "count", nullptr);
2182d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
2192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  check_jni_abort_catcher.Check("sig == null");
220cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes}
221cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
222cdf53120cd5a73cbedc1654e22542848468c0d2fElliott HughesTEST_F(JniInternalTest, GetStaticFieldID) {
223cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
2242d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(jlnsfe, nullptr);
225cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass c = env_->FindClass("java/lang/String");
2262d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
227cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
228cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Wrong type.
229cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J");
2302d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
2312d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
232cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
233b17d08b6ef0d36038e408dd79960293bb62ec1d9Ian Rogers  // Wrong type where type doesn't exist.
234b17d08b6ef0d36038e408dd79960293bb62ec1d9Ian Rogers  fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Lrod/jane/freddy;");
2352d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
2362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
237b17d08b6ef0d36038e408dd79960293bb62ec1d9Ian Rogers
238cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Wrong name.
239cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
2402d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
2412d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
242cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
243cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Good declared field lookup.
244cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
2452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(nullptr, fid);
2462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(fid, nullptr);
247cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  EXPECT_FALSE(env_->ExceptionCheck());
248cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
249cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Not static.
250cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetStaticFieldID(c, "count", "I");
2512d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
2522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
2532d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
2542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Bad arguments.
2552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher check_jni_abort_catcher;
2562d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  fid = env_->GetStaticFieldID(nullptr, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
2572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
2582d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  check_jni_abort_catcher.Check("java_class == null");
2592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  fid = env_->GetStaticFieldID(c, nullptr, "Ljava/util/Comparator;");
2602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
2612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  check_jni_abort_catcher.Check("name == null");
2622d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", nullptr);
2632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
2642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  check_jni_abort_catcher.Check("sig == null");
265cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes}
266cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2674dd71f1538a8d788c56c77378a59ce32afa519d7Ian RogersTEST_F(JniInternalTest, GetMethodID) {
2684dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlobject = env_->FindClass("java/lang/Object");
2694dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlstring = env_->FindClass("java/lang/String");
2704dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
271004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  jclass jncrbc = env_->FindClass("java/nio/channels/ReadableByteChannel");
2724dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
273004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  // Sanity check that no exceptions are pending.
274cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  ASSERT_FALSE(env_->ExceptionCheck());
2754dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
2764dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
277004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  // a pending exception.
2784dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jmethodID method = env_->GetMethodID(jlobject, "foo", "()V");
2792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, method);
2802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsme);
2814dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
282004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  // Check that java.lang.Object.equals() does exist.
2834dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
2842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(nullptr, method);
2854dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
2864dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
2874dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // Check that GetMethodID for java.lang.String.valueOf(int) fails as the
288004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  // method is static.
2894dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
2902d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, method);
2912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsme);
292ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom
293004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  // Check that GetMethodID for java.lang.NoSuchMethodError.<init>(String) finds the constructor.
294ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  method = env_->GetMethodID(jlnsme, "<init>", "(Ljava/lang/String;)V");
2952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(nullptr, method);
296ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_FALSE(env_->ExceptionCheck());
2972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
298004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  // Check that GetMethodID can find a interface method inherited from another interface.
299004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  method = env_->GetMethodID(jncrbc, "close", "()V");
300004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  EXPECT_NE(nullptr, method);
301004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  EXPECT_FALSE(env_->ExceptionCheck());
302004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom
3032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Bad arguments.
3042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher check_jni_abort_catcher;
3052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  method = env_->GetMethodID(nullptr, "<init>", "(Ljava/lang/String;)V");
3062d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, method);
3072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  check_jni_abort_catcher.Check("java_class == null");
3082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  method = env_->GetMethodID(jlnsme, nullptr, "(Ljava/lang/String;)V");
3092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, method);
3102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  check_jni_abort_catcher.Check("name == null");
3112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  method = env_->GetMethodID(jlnsme, "<init>", nullptr);
3122d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, method);
3132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  check_jni_abort_catcher.Check("sig == null");
3144dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers}
3154dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
3164dd71f1538a8d788c56c77378a59ce32afa519d7Ian RogersTEST_F(JniInternalTest, GetStaticMethodID) {
3174dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlobject = env_->FindClass("java/lang/Object");
3184dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
3194dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
3204dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // Sanity check that no exceptions are pending
321cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  ASSERT_FALSE(env_->ExceptionCheck());
3224dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
3234dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
3244dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // a pending exception
3254dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V");
3262d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, method);
3272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsme);
3284dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
3294dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as
3304dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // the method is not static
3314dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
3322d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, method);
3332d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsme);
3344dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
3354dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // Check that java.lang.String.valueOf(int) does exist
3364dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlstring = env_->FindClass("java/lang/String");
3372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  method = env_->GetStaticMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
3382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(nullptr, method);
3394dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
3402d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
3412d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Bad arguments.
3422d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher check_jni_abort_catcher;
3432d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  method = env_->GetStaticMethodID(nullptr, "valueOf", "(I)Ljava/lang/String;");
3442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, method);
3452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  check_jni_abort_catcher.Check("java_class == null");
3462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  method = env_->GetStaticMethodID(jlstring, nullptr, "(I)Ljava/lang/String;");
3472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, method);
3482d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  check_jni_abort_catcher.Check("name == null");
3492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  method = env_->GetStaticMethodID(jlstring, "valueOf", nullptr);
3502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, method);
3512d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  check_jni_abort_catcher.Check("sig == null");
3524dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers}
3534dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
354cdf53120cd5a73cbedc1654e22542848468c0d2fElliott HughesTEST_F(JniInternalTest, FromReflectedField_ToReflectedField) {
355cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass jlrField = env_->FindClass("java/lang/reflect/Field");
356cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass c = env_->FindClass("java/lang/String");
3572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
358cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jfieldID fid = env_->GetFieldID(c, "count", "I");
3592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(fid, nullptr);
360cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Turn the fid into a java.lang.reflect.Field...
361cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jobject field = env_->ToReflectedField(c, fid, JNI_FALSE);
3622d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
363cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  ASSERT_TRUE(env_->IsInstanceOf(field, jlrField));
364cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // ...and back again.
365cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jfieldID fid2 = env_->FromReflectedField(field);
3662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(fid2, nullptr);
367ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  // Make sure we can actually use it.
368ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  jstring s = env_->NewStringUTF("poop");
369ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  ASSERT_EQ(4, env_->GetIntField(s, fid2));
3702d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
3712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Bad arguments.
3722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher check_jni_abort_catcher;
3732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  field = env_->ToReflectedField(c, nullptr, JNI_FALSE);
3742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(field, nullptr);
3752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  check_jni_abort_catcher.Check("fid == null");
3762d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  fid2 = env_->FromReflectedField(nullptr);
3772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_EQ(fid2, nullptr);
3782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  check_jni_abort_catcher.Check("jlr_field == null");
379cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes}
380cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
381cdf53120cd5a73cbedc1654e22542848468c0d2fElliott HughesTEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
382cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass jlrMethod = env_->FindClass("java/lang/reflect/Method");
383cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass c = env_->FindClass("java/lang/String");
3842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
385cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jmethodID mid = env_->GetMethodID(c, "length", "()I");
3862d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(mid, nullptr);
387cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Turn the mid into a java.lang.reflect.Method...
388cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
3892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
390cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod));
391cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // ...and back again.
392cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jmethodID mid2 = env_->FromReflectedMethod(method);
3932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(mid2, nullptr);
394ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  // Make sure we can actually use it.
395ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  jstring s = env_->NewStringUTF("poop");
3965d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers  ASSERT_EQ(4, env_->CallIntMethod(s, mid2));
3972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
3982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Bad arguments.
3992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher check_jni_abort_catcher;
4002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  method = env_->ToReflectedMethod(c, nullptr, JNI_FALSE);
4012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(method, nullptr);
4022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  check_jni_abort_catcher.Check("mid == null");
4032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  mid2 = env_->FromReflectedMethod(method);
4042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_EQ(mid2, nullptr);
4052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  check_jni_abort_catcher.Check("jlr_method == null");
406cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes}
407cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
4082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogersstatic void BogusMethod() {
4092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // You can't pass nullptr function pointers to RegisterNatives.
4105174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes}
4115174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
4122d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, RegisterAndUnregisterNatives) {
4134dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlobject = env_->FindClass("java/lang/Object");
4144dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
4154dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
4162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Sanity check that no exceptions are pending.
417cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  ASSERT_FALSE(env_->ExceptionCheck());
4184dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
4192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Check that registering to a non-existent java.lang.Object.foo() causes a NoSuchMethodError.
4204dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  {
4212d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    JNINativeMethod methods[] = { { "foo", "()V", nullptr } };
4222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
4234dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  }
4242d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsme);
4254dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
4262d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Check that registering non-native methods causes a NoSuchMethodError.
4274dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  {
4282d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    JNINativeMethod methods[] = { { "equals", "(Ljava/lang/Object;)Z", nullptr } };
4292d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
4304dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  }
4312d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsme);
4324dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
4332d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Check that registering native methods is successful.
4344dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  {
435b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes    JNINativeMethod methods[] = { { "notify", "()V", reinterpret_cast<void*>(BogusMethod) } };
4362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_OK);
4372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  }
4382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
4392d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->UnregisterNatives(jlobject), JNI_OK);
4402d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
4412d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Check that registering no methods isn't a failure.
4422d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  {
4432d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    JNINativeMethod methods[] = { };
4442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 0), JNI_OK);
4452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  }
4462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
4472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->UnregisterNatives(jlobject), JNI_OK);
4482d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
4492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Check that registering a -ve number of methods is a failure.
4502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher check_jni_abort_catcher;
4512d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  for (int i = -10; i < 0; ++i) {
4522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    JNINativeMethod methods[] = { };
4532d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->RegisterNatives(jlobject, methods, i), JNI_ERR);
4542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    check_jni_abort_catcher.Check("negative method count: ");
4554dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  }
4564dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
4575174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
4582d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Passing a class of null is a failure.
4592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  {
4602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    JNINativeMethod methods[] = { };
4612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->RegisterNatives(nullptr, methods, 0), JNI_ERR);
4622d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    check_jni_abort_catcher.Check("java_class == null");
4632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  }
4642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
4652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Passing methods as null is a failure.
4662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->RegisterNatives(jlobject, nullptr, 1), JNI_ERR);
4672d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  check_jni_abort_catcher.Check("methods == null");
4682d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
4692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Unregisters null is a failure.
4702d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->UnregisterNatives(nullptr), JNI_ERR);
4712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  check_jni_abort_catcher.Check("java_class == null");
4722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
4732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Unregistering a class with no natives is a warning.
4742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->UnregisterNatives(jlnsme), JNI_OK);
4754dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers}
4764dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
477ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#define EXPECT_PRIMITIVE_ARRAY(new_fn, \
478ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               get_region_fn, \
479ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               set_region_fn, \
480ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               get_elements_fn, \
481ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               release_elements_fn, \
482ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               scalar_type, \
483ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               expected_class_descriptor) \
4842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jsize size = 4; \
4852d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  \
4861d99e4549309d05007d041d058b1878de88e9585Ian Rogers  { \
4871d99e4549309d05007d041d058b1878de88e9585Ian Rogers    CheckJniAbortCatcher jni_abort_catcher; \
4881d99e4549309d05007d041d058b1878de88e9585Ian Rogers    /* Allocate an negative sized array and check it has the right failure type. */ \
4892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->new_fn(-1), nullptr); \
4901d99e4549309d05007d041d058b1878de88e9585Ian Rogers    jni_abort_catcher.Check("negative array length: -1"); \
4912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->new_fn(std::numeric_limits<jint>::min()), nullptr); \
4921d99e4549309d05007d041d058b1878de88e9585Ian Rogers    jni_abort_catcher.Check("negative array length: -2147483648"); \
4932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    /* Pass the array as null. */ \
4942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(0, env_->GetArrayLength(nullptr)); \
4952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("java_array == null"); \
4962d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->get_region_fn(nullptr, 0, 0, nullptr); \
4972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("java_array == null"); \
4982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->set_region_fn(nullptr, 0, 0, nullptr); \
4992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("java_array == null"); \
5002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->get_elements_fn(nullptr, nullptr); \
5012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("java_array == null"); \
5022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->release_elements_fn(nullptr, nullptr, 0); \
5032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("java_array == null"); \
5042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    /* Pass the elements for region as null. */ \
5052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    scalar_type ## Array a = env_->new_fn(size); \
5062d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->get_region_fn(a, 0, size, nullptr); \
5072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("buf == null"); \
5082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->set_region_fn(a, 0, size, nullptr); \
5092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("buf == null"); \
5101d99e4549309d05007d041d058b1878de88e9585Ian Rogers  } \
511814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Allocate an array and check it has the right type and length. */ \
512814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  scalar_type ## Array a = env_->new_fn(size); \
5132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(a, nullptr); \
514814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(a, env_->FindClass(expected_class_descriptor))); \
515814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(size, env_->GetArrayLength(a)); \
516d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
517d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  /* GetPrimitiveArrayRegion/SetPrimitiveArrayRegion */ \
518814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* AIOOBE for negative start offset. */ \
5192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->get_region_fn(a, -1, 1, nullptr); \
5202d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
5212d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->set_region_fn(a, -1, 1, nullptr); \
5222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
523d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
524814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* AIOOBE for negative length. */ \
5252d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->get_region_fn(a, 0, -1, nullptr); \
5262d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
5272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->set_region_fn(a, 0, -1, nullptr); \
5282d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
529d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
530814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* AIOOBE for buffer overrun. */ \
5312d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->get_region_fn(a, size - 1, size, nullptr); \
5322d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
5332d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->set_region_fn(a, size - 1, size, nullptr); \
5342d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
535d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
5362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  /* It's okay for the buffer to be nullptr as long as the length is 0. */ \
5372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->get_region_fn(a, 2, 0, nullptr); \
538d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  /* Even if the offset is invalid... */ \
5392d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->get_region_fn(a, 123, 0, nullptr); \
5402d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
541d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
5422d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  /* It's okay for the buffer to be nullptr as long as the length is 0. */ \
5432d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->set_region_fn(a, 2, 0, nullptr); \
544d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  /* Even if the offset is invalid... */ \
5452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->set_region_fn(a, 123, 0, nullptr); \
5462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
547d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
548814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Prepare a couple of buffers. */ \
549700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<scalar_type[]> src_buf(new scalar_type[size]); \
550700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<scalar_type[]> dst_buf(new scalar_type[size]); \
551814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  for (jsize i = 0; i < size; ++i) { src_buf[i] = scalar_type(i); } \
552814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  for (jsize i = 0; i < size; ++i) { dst_buf[i] = scalar_type(-1); } \
553d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
554814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Copy all of src_buf onto the heap. */ \
555ee0fa76b2e5d39ad36d1ff144b2d0270df81e606Elliott Hughes  env_->set_region_fn(a, 0, size, &src_buf[0]); \
556814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Copy back only part. */ \
557814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  env_->get_region_fn(a, 1, size - 2, &dst_buf[1]); \
558ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_NE(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
559ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    << "short copy equal"; \
560814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Copy the missing pieces. */ \
561ee0fa76b2e5d39ad36d1ff144b2d0270df81e606Elliott Hughes  env_->get_region_fn(a, 0, 1, &dst_buf[0]); \
562814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  env_->get_region_fn(a, size - 1, 1, &dst_buf[size - 1]); \
563ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
564ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    << "fixed copy not equal"; \
565814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Copy back the whole array. */ \
566ee0fa76b2e5d39ad36d1ff144b2d0270df81e606Elliott Hughes  env_->get_region_fn(a, 0, size, &dst_buf[0]); \
567ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
568ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    << "full copy not equal"; \
5697577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  /* GetPrimitiveArrayCritical */ \
5702d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  void* v = env_->GetPrimitiveArrayCritical(a, nullptr); \
571ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_EQ(memcmp(&src_buf[0], v, size * sizeof(scalar_type)), 0) \
572ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    << "GetPrimitiveArrayCritical not equal"; \
5737577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleasePrimitiveArrayCritical(a, v, 0); \
5747577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  /* GetXArrayElements */ \
5752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  scalar_type* xs = env_->get_elements_fn(a, nullptr); \
576ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_EQ(memcmp(&src_buf[0], xs, size * sizeof(scalar_type)), 0) \
577ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    << # get_elements_fn " not equal"; \
5787577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->release_elements_fn(a, xs, 0); \
579814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
580814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, BooleanArrays) {
581ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion,
582ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetBooleanArrayElements, ReleaseBooleanArrayElements, jboolean, "[Z");
583814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
584814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, ByteArrays) {
585ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion,
586ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetByteArrayElements, ReleaseByteArrayElements, jbyte, "[B");
587814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
588814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, CharArrays) {
589ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion,
590ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetCharArrayElements, ReleaseCharArrayElements, jchar, "[C");
591814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
592814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, DoubleArrays) {
593ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion,
594ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetDoubleArrayElements, ReleaseDoubleArrayElements, jdouble, "[D");
595814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
596814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, FloatArrays) {
597ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion,
598ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetFloatArrayElements, ReleaseFloatArrayElements, jfloat, "[F");
599814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
600814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, IntArrays) {
601ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion,
602ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetIntArrayElements, ReleaseIntArrayElements, jint, "[I");
603814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
604814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, LongArrays) {
605ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion,
606ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetLongArrayElements, ReleaseLongArrayElements, jlong, "[J");
607814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
608814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, ShortArrays) {
609ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion,
610ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetShortArrayElements, ReleaseShortArrayElements, jshort, "[S");
611d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes}
612d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes
6132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, GetPrimitiveArrayElementsOfWrongType) {
6142d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
6152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jbooleanArray array = env_->NewBooleanArray(10);
6162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jboolean is_copy;
6172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetByteArrayElements(reinterpret_cast<jbyteArray>(array), &is_copy), nullptr);
6182d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
6192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to get byte primitive array elements with an object of type boolean[]");
6202d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetShortArrayElements(reinterpret_cast<jshortArray>(array), &is_copy), nullptr);
6212d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
6222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to get short primitive array elements with an object of type boolean[]");
6232d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetCharArrayElements(reinterpret_cast<jcharArray>(array), &is_copy), nullptr);
6242d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
6252d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to get char primitive array elements with an object of type boolean[]");
6262d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetIntArrayElements(reinterpret_cast<jintArray>(array), &is_copy), nullptr);
6272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
6282d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to get int primitive array elements with an object of type boolean[]");
6292d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetLongArrayElements(reinterpret_cast<jlongArray>(array), &is_copy), nullptr);
6302d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
6312d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to get long primitive array elements with an object of type boolean[]");
6322d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetFloatArrayElements(reinterpret_cast<jfloatArray>(array), &is_copy), nullptr);
6332d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
6342d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to get float primitive array elements with an object of type boolean[]");
6352d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetDoubleArrayElements(reinterpret_cast<jdoubleArray>(array), &is_copy), nullptr);
6362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
6372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to get double primitive array elements with an object of type boolean[]");
6382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jbyteArray array2 = env_->NewByteArray(10);
639004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  EXPECT_EQ(env_->GetBooleanArrayElements(reinterpret_cast<jbooleanArray>(array2), &is_copy),
640004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom            nullptr);
6412d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
6422d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to get boolean primitive array elements with an object of type byte[]");
6432d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jobject object = env_->NewStringUTF("Test String");
644004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  EXPECT_EQ(env_->GetBooleanArrayElements(reinterpret_cast<jbooleanArray>(object), &is_copy),
645004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom            nullptr);
6462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
6472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to get boolean primitive array elements with an object of type java.lang.String");
6482d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers}
6492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
6502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, ReleasePrimitiveArrayElementsOfWrongType) {
6512d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
6522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jbooleanArray array = env_->NewBooleanArray(10);
6532d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(array != nullptr);
6542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jboolean is_copy;
6552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jboolean* elements = env_->GetBooleanArrayElements(array, &is_copy);
6562d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(elements != nullptr);
6572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->ReleaseByteArrayElements(reinterpret_cast<jbyteArray>(array),
6582d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                 reinterpret_cast<jbyte*>(elements), 0);
6592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
6602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to release byte primitive array elements with an object of type boolean[]");
6612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->ReleaseShortArrayElements(reinterpret_cast<jshortArray>(array),
6622d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                  reinterpret_cast<jshort*>(elements), 0);
6632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
6642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to release short primitive array elements with an object of type boolean[]");
6652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->ReleaseCharArrayElements(reinterpret_cast<jcharArray>(array),
6662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                 reinterpret_cast<jchar*>(elements), 0);
6672d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
6682d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to release char primitive array elements with an object of type boolean[]");
6692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->ReleaseIntArrayElements(reinterpret_cast<jintArray>(array),
6702d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                reinterpret_cast<jint*>(elements), 0);
6712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
6722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to release int primitive array elements with an object of type boolean[]");
6732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->ReleaseLongArrayElements(reinterpret_cast<jlongArray>(array),
6742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                 reinterpret_cast<jlong*>(elements), 0);
6752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
6762d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to release long primitive array elements with an object of type boolean[]");
6772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->ReleaseFloatArrayElements(reinterpret_cast<jfloatArray>(array),
6782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                  reinterpret_cast<jfloat*>(elements), 0);
6792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
6802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to release float primitive array elements with an object of type boolean[]");
6812d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->ReleaseDoubleArrayElements(reinterpret_cast<jdoubleArray>(array),
6822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                  reinterpret_cast<jdouble*>(elements), 0);
6832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
6842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to release double primitive array elements with an object of type boolean[]");
6852d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jbyteArray array2 = env_->NewByteArray(10);
6862d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->ReleaseBooleanArrayElements(reinterpret_cast<jbooleanArray>(array2), elements, 0);
6872d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
6882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to release boolean primitive array elements with an object of type byte[]");
6892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jobject object = env_->NewStringUTF("Test String");
6902d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->ReleaseBooleanArrayElements(reinterpret_cast<jbooleanArray>(object), elements, 0);
6912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
692004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom      "attempt to release boolean primitive array elements with an object of type "
693004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom      "java.lang.String");
6942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers}
6952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, GetReleasePrimitiveArrayCriticalOfWrongType) {
6962d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
6972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jobject object = env_->NewStringUTF("Test String");
6982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jboolean is_copy;
6992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  void* elements = env_->GetPrimitiveArrayCritical(reinterpret_cast<jarray>(object), &is_copy);
7002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("expected primitive array, given java.lang.String");
7012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->ReleasePrimitiveArrayCritical(reinterpret_cast<jarray>(object), elements, 0);
7022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("expected primitive array, given java.lang.String");
7032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers}
7042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
7052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, GetPrimitiveArrayRegionElementsOfWrongType) {
7062d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
7072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  constexpr size_t kLength = 10;
7082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jbooleanArray array = env_->NewBooleanArray(kLength);
7092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(array != nullptr);
7102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jboolean elements[kLength];
7112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetByteArrayRegion(reinterpret_cast<jbyteArray>(array), 0, kLength,
7122d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                           reinterpret_cast<jbyte*>(elements));
7132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
7142d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to get region of byte primitive array elements with an object of type boolean[]");
7152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetShortArrayRegion(reinterpret_cast<jshortArray>(array), 0, kLength,
7162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                            reinterpret_cast<jshort*>(elements));
7172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
7182d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to get region of short primitive array elements with an object of type boolean[]");
7192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetCharArrayRegion(reinterpret_cast<jcharArray>(array), 0, kLength,
7202d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                           reinterpret_cast<jchar*>(elements));
7212d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
7222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to get region of char primitive array elements with an object of type boolean[]");
7232d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetIntArrayRegion(reinterpret_cast<jintArray>(array), 0, kLength,
7242d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                          reinterpret_cast<jint*>(elements));
7252d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
7262d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to get region of int primitive array elements with an object of type boolean[]");
7272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetLongArrayRegion(reinterpret_cast<jlongArray>(array), 0, kLength,
7282d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                           reinterpret_cast<jlong*>(elements));
7292d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
7302d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to get region of long primitive array elements with an object of type boolean[]");
7312d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetFloatArrayRegion(reinterpret_cast<jfloatArray>(array), 0, kLength,
7322d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                            reinterpret_cast<jfloat*>(elements));
7332d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
7342d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to get region of float primitive array elements with an object of type boolean[]");
7352d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetDoubleArrayRegion(reinterpret_cast<jdoubleArray>(array), 0, kLength,
7362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                           reinterpret_cast<jdouble*>(elements));
7372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
7382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to get region of double primitive array elements with an object of type boolean[]");
7392d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jbyteArray array2 = env_->NewByteArray(10);
7402d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(array2), 0, kLength,
7412d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                              reinterpret_cast<jboolean*>(elements));
7422d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
7432d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to get region of boolean primitive array elements with an object of type byte[]");
7442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jobject object = env_->NewStringUTF("Test String");
7452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(object), 0, kLength,
7462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                              reinterpret_cast<jboolean*>(elements));
7472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
748004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom      "attempt to get region of boolean primitive array elements with an object of type "
749004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom      "java.lang.String");
7502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers}
7512d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
7522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, SetPrimitiveArrayRegionElementsOfWrongType) {
7532d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
7542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  constexpr size_t kLength = 10;
7552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jbooleanArray array = env_->NewBooleanArray(kLength);
7562d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(array != nullptr);
7572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jboolean elements[kLength];
7582d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->SetByteArrayRegion(reinterpret_cast<jbyteArray>(array), 0, kLength,
7592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                           reinterpret_cast<jbyte*>(elements));
7602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
7612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to set region of byte primitive array elements with an object of type boolean[]");
7622d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->SetShortArrayRegion(reinterpret_cast<jshortArray>(array), 0, kLength,
7632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                            reinterpret_cast<jshort*>(elements));
7642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
7652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to set region of short primitive array elements with an object of type boolean[]");
7662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->SetCharArrayRegion(reinterpret_cast<jcharArray>(array), 0, kLength,
7672d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                           reinterpret_cast<jchar*>(elements));
7682d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
7692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to set region of char primitive array elements with an object of type boolean[]");
7702d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->SetIntArrayRegion(reinterpret_cast<jintArray>(array), 0, kLength,
7712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                          reinterpret_cast<jint*>(elements));
7722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
7732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to set region of int primitive array elements with an object of type boolean[]");
7742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->SetLongArrayRegion(reinterpret_cast<jlongArray>(array), 0, kLength,
7752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                           reinterpret_cast<jlong*>(elements));
7762d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
7772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to set region of long primitive array elements with an object of type boolean[]");
7782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->SetFloatArrayRegion(reinterpret_cast<jfloatArray>(array), 0, kLength,
7792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                            reinterpret_cast<jfloat*>(elements));
7802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
7812d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to set region of float primitive array elements with an object of type boolean[]");
7822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->SetDoubleArrayRegion(reinterpret_cast<jdoubleArray>(array), 0, kLength,
7832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                           reinterpret_cast<jdouble*>(elements));
7842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
7852d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to set region of double primitive array elements with an object of type boolean[]");
7862d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jbyteArray array2 = env_->NewByteArray(10);
7872d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->SetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(array2), 0, kLength,
7882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                              reinterpret_cast<jboolean*>(elements));
7892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
7902d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      "attempt to set region of boolean primitive array elements with an object of type byte[]");
7912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jobject object = env_->NewStringUTF("Test String");
7922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->SetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(object), 0, kLength,
7932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                              reinterpret_cast<jboolean*>(elements));
7942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check(
795004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom      "attempt to set region of boolean primitive array elements with an object of type "
796004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom      "java.lang.String");
7972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers}
7982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
799f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott HughesTEST_F(JniInternalTest, NewObjectArray) {
800bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  jclass element_class = env_->FindClass("java/lang/String");
8012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(element_class, nullptr);
802bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  jclass array_class = env_->FindClass("[Ljava/lang/String;");
8032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(array_class, nullptr);
804f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
8051d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jobjectArray a = env_->NewObjectArray(0, element_class, nullptr);
8062d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(a, nullptr);
807bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
808bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  EXPECT_EQ(0, env_->GetArrayLength(a));
809f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
8101d99e4549309d05007d041d058b1878de88e9585Ian Rogers  a = env_->NewObjectArray(1, element_class, nullptr);
8112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(a, nullptr);
812bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
813bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  EXPECT_EQ(1, env_->GetArrayLength(a));
8141d99e4549309d05007d041d058b1878de88e9585Ian Rogers  EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), nullptr));
8151d99e4549309d05007d041d058b1878de88e9585Ian Rogers
8162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Negative array length checks.
8171d99e4549309d05007d041d058b1878de88e9585Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
8181d99e4549309d05007d041d058b1878de88e9585Ian Rogers  env_->NewObjectArray(-1, element_class, nullptr);
8191d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jni_abort_catcher.Check("negative array length: -1");
8201d99e4549309d05007d041d058b1878de88e9585Ian Rogers
8211d99e4549309d05007d041d058b1878de88e9585Ian Rogers  env_->NewObjectArray(std::numeric_limits<jint>::min(), element_class, nullptr);
8221d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jni_abort_catcher.Check("negative array length: -2147483648");
8231d99e4549309d05007d041d058b1878de88e9585Ian Rogers}
8241d99e4549309d05007d041d058b1878de88e9585Ian Rogers
8251d99e4549309d05007d041d058b1878de88e9585Ian RogersTEST_F(JniInternalTest, NewObjectArrayWithPrimitiveClasses) {
8261d99e4549309d05007d041d058b1878de88e9585Ian Rogers  const char* primitive_descriptors = "VZBSCIJFD";
8271d99e4549309d05007d041d058b1878de88e9585Ian Rogers  const char* primitive_names[] = {
8281d99e4549309d05007d041d058b1878de88e9585Ian Rogers      "void", "boolean", "byte", "short", "char", "int", "long", "float", "double"
8291d99e4549309d05007d041d058b1878de88e9585Ian Rogers  };
8301d99e4549309d05007d041d058b1878de88e9585Ian Rogers  ASSERT_EQ(strlen(primitive_descriptors), arraysize(primitive_names));
8311d99e4549309d05007d041d058b1878de88e9585Ian Rogers
8321d99e4549309d05007d041d058b1878de88e9585Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
8331d99e4549309d05007d041d058b1878de88e9585Ian Rogers  for (size_t i = 0; i < strlen(primitive_descriptors); ++i) {
8342d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->NewObjectArray(0, nullptr, nullptr);
8352d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("element_jclass == null");
8361d99e4549309d05007d041d058b1878de88e9585Ian Rogers    jclass primitive_class = GetPrimitiveClass(primitive_descriptors[i]);
8371d99e4549309d05007d041d058b1878de88e9585Ian Rogers    env_->NewObjectArray(1, primitive_class, nullptr);
8381d99e4549309d05007d041d058b1878de88e9585Ian Rogers    std::string error_msg(StringPrintf("not an object type: %s", primitive_names[i]));
8391d99e4549309d05007d041d058b1878de88e9585Ian Rogers    jni_abort_catcher.Check(error_msg.c_str());
8401d99e4549309d05007d041d058b1878de88e9585Ian Rogers  }
8411d99e4549309d05007d041d058b1878de88e9585Ian Rogers}
8421d99e4549309d05007d041d058b1878de88e9585Ian Rogers
8431d99e4549309d05007d041d058b1878de88e9585Ian RogersTEST_F(JniInternalTest, NewObjectArrayWithInitialValue) {
8441d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jclass element_class = env_->FindClass("java/lang/String");
8452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(element_class, nullptr);
8461d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jclass array_class = env_->FindClass("[Ljava/lang/String;");
8472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(array_class, nullptr);
8487577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
8497577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jstring s = env_->NewStringUTF("poop");
8501d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jobjectArray a = env_->NewObjectArray(2, element_class, s);
8512d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(a, nullptr);
8527577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
8537577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(2, env_->GetArrayLength(a));
8547577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), s));
8557577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 1), s));
8561d99e4549309d05007d041d058b1878de88e9585Ian Rogers
8571d99e4549309d05007d041d058b1878de88e9585Ian Rogers  // Attempt to incorrect create an array of strings with initial value of string arrays.
8581d99e4549309d05007d041d058b1878de88e9585Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
8591d99e4549309d05007d041d058b1878de88e9585Ian Rogers  env_->NewObjectArray(2, element_class, a);
8601d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jni_abort_catcher.Check("cannot assign object of type 'java.lang.String[]' to array with element "
8611d99e4549309d05007d041d058b1878de88e9585Ian Rogers                          "type of 'java.lang.String'");
862bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes}
863f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
864bd9359912e5398799f60649b86ae80644ec72627Elliott HughesTEST_F(JniInternalTest, GetArrayLength) {
865bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  // Already tested in NewObjectArray/NewPrimitiveArray.
8668a26c5c4c74b09e2887593c733a22652a9f80d7cElliott Hughes}
8678a26c5c4c74b09e2887593c733a22652a9f80d7cElliott Hughes
86837f7a40f6789bb287f287a9af00777af9d6428eeElliott HughesTEST_F(JniInternalTest, GetObjectClass) {
86937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass string_class = env_->FindClass("java/lang/String");
8702d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(string_class, nullptr);
87137f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass class_class = env_->FindClass("java/lang/Class");
8722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(class_class, nullptr);
87337f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
87437f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jstring s = env_->NewStringUTF("poop");
87537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass c = env_->GetObjectClass(s);
87637f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  ASSERT_TRUE(env_->IsSameObject(string_class, c));
87737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
87837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass c2 = env_->GetObjectClass(c);
87937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2)));
8802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
8812d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Null as object should fail.
8822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
8832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetObjectClass(nullptr), nullptr);
8842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_object == null");
88537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes}
88637f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
887885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott HughesTEST_F(JniInternalTest, GetSuperclass) {
888885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jclass object_class = env_->FindClass("java/lang/Object");
8892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(object_class, nullptr);
890885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jclass string_class = env_->FindClass("java/lang/String");
8912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(string_class, nullptr);
892dc18020e83aa1261d4f661f1f9330bda20dffd71Ian Rogers  jclass runnable_interface = env_->FindClass("java/lang/Runnable");
8932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(runnable_interface, nullptr);
894885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class)));
8952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_EQ(env_->GetSuperclass(object_class), nullptr);
896dc18020e83aa1261d4f661f1f9330bda20dffd71Ian Rogers  ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(runnable_interface)));
8972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
8982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Null as class should fail.
8992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
9002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetSuperclass(nullptr), nullptr);
9012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_class == null");
902885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes}
903885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
90437f7a40f6789bb287f287a9af00777af9d6428eeElliott HughesTEST_F(JniInternalTest, IsAssignableFrom) {
90537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass object_class = env_->FindClass("java/lang/Object");
9062d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(object_class, nullptr);
90737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass string_class = env_->FindClass("java/lang/String");
9082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(string_class, nullptr);
90937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
91037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  ASSERT_TRUE(env_->IsAssignableFrom(object_class, string_class));
91137f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  ASSERT_FALSE(env_->IsAssignableFrom(string_class, object_class));
9122d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
9132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Null as either class should fail.
9142d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
9152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->IsAssignableFrom(nullptr, string_class), JNI_FALSE);
9162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_class1 == null");
9172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->IsAssignableFrom(object_class, nullptr), JNI_FALSE);
9182d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_class2 == null");
91937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes}
92037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
921b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott HughesTEST_F(JniInternalTest, GetObjectRefType) {
922b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jclass local = env_->FindClass("java/lang/Object");
9232d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(local != nullptr);
924b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(local));
925b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
926b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jobject global = env_->NewGlobalRef(local);
927b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ(JNIGlobalRefType, env_->GetObjectRefType(global));
928b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
929b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jweak weak_global = env_->NewWeakGlobalRef(local);
930b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ(JNIWeakGlobalRefType, env_->GetObjectRefType(weak_global));
931b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
932b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jobject invalid = reinterpret_cast<jobject>(this);
933b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(invalid));
934b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
935b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  // TODO: invoke a native method and test that its arguments are considered local references.
9362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
9372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Null as object should fail.
9382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
9392d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(nullptr));
9402d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_object == null");
941b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes}
942b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
9430859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu ChartierTEST_F(JniInternalTest, StaleWeakGlobal) {
9440859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  jclass java_lang_Class = env_->FindClass("java/lang/Class");
9452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(java_lang_Class, nullptr);
9462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jobjectArray local_ref = env_->NewObjectArray(1, java_lang_Class, nullptr);
9472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(local_ref, nullptr);
9480859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  jweak weak_global = env_->NewWeakGlobalRef(local_ref);
9492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(weak_global, nullptr);
9500859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  env_->DeleteLocalRef(local_ref);
9510859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  Runtime::Current()->GetHeap()->CollectGarbage(false);  // GC should clear the weak global.
9520859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  jobject new_global_ref = env_->NewGlobalRef(weak_global);
9532d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(new_global_ref, nullptr);
9540859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  jobject new_local_ref = env_->NewLocalRef(weak_global);
9552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(new_local_ref, nullptr);
9560859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier}
9570859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier
9588a26c5c4c74b09e2887593c733a22652a9f80d7cElliott HughesTEST_F(JniInternalTest, NewStringUTF) {
9592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->NewStringUTF(nullptr), nullptr);
960814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  jstring s;
961814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
962814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  s = env_->NewStringUTF("");
9632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(s, nullptr);
964814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(0, env_->GetStringLength(s));
965814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(0, env_->GetStringUTFLength(s));
966814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  s = env_->NewStringUTF("hello");
9672d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(s, nullptr);
968814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(5, env_->GetStringLength(s));
969814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(5, env_->GetStringUTFLength(s));
970814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
971814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  // TODO: check some non-ASCII strings.
972814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
973814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
974814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, NewString) {
975814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  jchar chars[] = { 'h', 'i' };
976814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  jstring s;
977814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  s = env_->NewString(chars, 0);
9782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(s, nullptr);
979814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(0, env_->GetStringLength(s));
980814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(0, env_->GetStringUTFLength(s));
981814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  s = env_->NewString(chars, 2);
9822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(s, nullptr);
983814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(2, env_->GetStringLength(s));
984814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(2, env_->GetStringUTFLength(s));
985814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
9868a26c5c4c74b09e2887593c733a22652a9f80d7cElliott Hughes  // TODO: check some non-ASCII strings.
987f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes}
988f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
98925e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse WilsonTEST_F(JniInternalTest, NewStringNullCharsZeroLength) {
9901d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jstring s = env_->NewString(nullptr, 0);
9912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(s, nullptr);
99225e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse Wilson  EXPECT_EQ(0, env_->GetStringLength(s));
99325e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse Wilson}
99425e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse Wilson
9951d99e4549309d05007d041d058b1878de88e9585Ian RogersTEST_F(JniInternalTest, NewStringNullCharsNonzeroLength) {
9961d99e4549309d05007d041d058b1878de88e9585Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
9971d99e4549309d05007d041d058b1878de88e9585Ian Rogers  env_->NewString(nullptr, 1);
9981d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jni_abort_catcher.Check("chars == null && char_count > 0");
9991d99e4549309d05007d041d058b1878de88e9585Ian Rogers}
10001d99e4549309d05007d041d058b1878de88e9585Ian Rogers
10011d99e4549309d05007d041d058b1878de88e9585Ian RogersTEST_F(JniInternalTest, NewStringNegativeLength) {
10021d99e4549309d05007d041d058b1878de88e9585Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
10031d99e4549309d05007d041d058b1878de88e9585Ian Rogers  env_->NewString(nullptr, -1);
10041d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jni_abort_catcher.Check("char_count < 0: -1");
10051d99e4549309d05007d041d058b1878de88e9585Ian Rogers  env_->NewString(nullptr, std::numeric_limits<jint>::min());
10061d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jni_abort_catcher.Check("char_count < 0: -2147483648");
100725e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse Wilson}
100825e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse Wilson
1009b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott HughesTEST_F(JniInternalTest, GetStringLength_GetStringUTFLength) {
1010b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  // Already tested in the NewString/NewStringUTF tests.
1011b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes}
1012b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1013b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott HughesTEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) {
1014b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jstring s = env_->NewStringUTF("hello");
10152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(s != nullptr);
1016b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
10172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, -1, 0, nullptr);
10182d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
10192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, 0, -1, nullptr);
10202d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
10212d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, 0, 10, nullptr);
10222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
10232d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, 10, 1, nullptr);
10242d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
1025b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1026b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jchar chars[4] = { 'x', 'x', 'x', 'x' };
1027b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  env_->GetStringRegion(s, 1, 2, &chars[1]);
1028b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('x', chars[0]);
1029b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('e', chars[1]);
1030b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('l', chars[2]);
1031b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('x', chars[3]);
1032b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
10332d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // It's okay for the buffer to be nullptr as long as the length is 0.
10342d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, 2, 0, nullptr);
1035d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  // Even if the offset is invalid...
10362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, 123, 0, nullptr);
10372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
10382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
10392d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, -1, 0, nullptr);
10402d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
10412d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, 0, -1, nullptr);
10422d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
10432d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, 0, 10, nullptr);
10442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
10452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, 10, 1, nullptr);
10462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
1047b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1048b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  char bytes[4] = { 'x', 'x', 'x', 'x' };
1049b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  env_->GetStringUTFRegion(s, 1, 2, &bytes[1]);
1050b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('x', bytes[0]);
1051b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('e', bytes[1]);
1052b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('l', bytes[2]);
1053b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('x', bytes[3]);
1054d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes
10552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // It's okay for the buffer to be nullptr as long as the length is 0.
10562d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, 2, 0, nullptr);
1057d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  // Even if the offset is invalid...
10582d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, 123, 0, nullptr);
10592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
1060b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes}
1061b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
10627577075b147fd8fa37ca41e7a32d1124676776ceElliott HughesTEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) {
10632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Passing in a nullptr jstring is ignored normally, but caught by -Xcheck:jni.
1064b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  {
1065b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    CheckJniAbortCatcher check_jni_abort_catcher;
10662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->GetStringUTFChars(nullptr, nullptr), nullptr);
106756ef042065ce282f8f01a0f31f5cce868a60ede8Elliott Hughes    check_jni_abort_catcher.Check("GetStringUTFChars received null jstring");
1068b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
10697577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
10707577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jstring s = env_->NewStringUTF("hello");
10712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(s != nullptr);
10727577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
10732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  const char* utf = env_->GetStringUTFChars(s, nullptr);
10747577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_STREQ("hello", utf);
10757577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringUTFChars(s, utf);
10767577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
10777577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jboolean is_copy = JNI_FALSE;
10787577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  utf = env_->GetStringUTFChars(s, &is_copy);
10797577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(JNI_TRUE, is_copy);
10807577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_STREQ("hello", utf);
10817577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringUTFChars(s, utf);
10827577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes}
10837577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
10847577075b147fd8fa37ca41e7a32d1124676776ceElliott HughesTEST_F(JniInternalTest, GetStringChars_ReleaseStringChars) {
10857577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jstring s = env_->NewStringUTF("hello");
108656890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  ScopedObjectAccess soa(env_);
108756890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  mirror::String* s_m = soa.Decode<mirror::String*>(s);
10882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(s != nullptr);
10897577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
10907577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
10912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  const jchar* chars = env_->GetStringChars(s, nullptr);
10927577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[0], chars[0]);
10937577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[1], chars[1]);
10947577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[2], chars[2]);
10957577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[3], chars[3]);
10967577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[4], chars[4]);
10977577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringChars(s, chars);
10987577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
10997577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jboolean is_copy = JNI_FALSE;
11007577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  chars = env_->GetStringChars(s, &is_copy);
110156890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  if (Runtime::Current()->GetHeap()->IsMovableObject(s_m->GetCharArray())) {
110256890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    EXPECT_EQ(JNI_TRUE, is_copy);
110356890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  } else {
110456890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    EXPECT_EQ(JNI_FALSE, is_copy);
110556890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  }
11067577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[0], chars[0]);
11077577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[1], chars[1]);
11087577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[2], chars[2]);
11097577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[3], chars[3]);
11107577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[4], chars[4]);
11117577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringChars(s, chars);
11127577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes}
11137577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
11147577075b147fd8fa37ca41e7a32d1124676776ceElliott HughesTEST_F(JniInternalTest, GetStringCritical_ReleaseStringCritical) {
11157577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jstring s = env_->NewStringUTF("hello");
11162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(s != nullptr);
11177577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
11187577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
11192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  const jchar* chars = env_->GetStringCritical(s, nullptr);
11207577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[0], chars[0]);
11217577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[1], chars[1]);
11227577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[2], chars[2]);
11237577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[3], chars[3]);
11247577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[4], chars[4]);
11257577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringCritical(s, chars);
11267577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
112756890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  jboolean is_copy = JNI_TRUE;
11287577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  chars = env_->GetStringCritical(s, &is_copy);
112956890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  EXPECT_EQ(JNI_FALSE, is_copy);
11307577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[0], chars[0]);
11317577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[1], chars[1]);
11327577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[2], chars[2]);
11337577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[3], chars[3]);
11347577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[4], chars[4]);
11357577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringCritical(s, chars);
11367577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes}
11377577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
1138814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) {
1139b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  jclass java_lang_Class = env_->FindClass("java/lang/Class");
11402d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(java_lang_Class != nullptr);
1141289da82ae82438ab3aed1898c82fd87c16846e74Elliott Hughes
11422d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jobjectArray array = env_->NewObjectArray(1, java_lang_Class, nullptr);
11432d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(array, nullptr);
11442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetObjectArrayElement(array, 0), nullptr);
1145b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  env_->SetObjectArrayElement(array, 0, java_lang_Class);
1146b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), java_lang_Class));
1147a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes
1148a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes  // ArrayIndexOutOfBounds for negative index.
1149b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  env_->SetObjectArrayElement(array, -1, java_lang_Class);
11502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_);
1151a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes
1152a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes  // ArrayIndexOutOfBounds for too-large index.
1153b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  env_->SetObjectArrayElement(array, 1, java_lang_Class);
11542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_);
1155a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes
1156b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  // ArrayStoreException thrown for bad types.
1157b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  env_->SetObjectArrayElement(array, 0, env_->NewStringUTF("not a jclass!"));
11582d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(ase_);
11592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
11602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Null as array should fail.
11612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
11622d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, env_->GetObjectArrayElement(nullptr, 0));
11632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_array == null");
11642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->SetObjectArrayElement(nullptr, 0, nullptr);
11652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_array == null");
1166289da82ae82438ab3aed1898c82fd87c16846e74Elliott Hughes}
1167289da82ae82438ab3aed1898c82fd87c16846e74Elliott Hughes
1168885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes#define EXPECT_STATIC_PRIMITIVE_FIELD(type, field_name, sig, value1, value2) \
1169885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  do { \
1170885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \
11712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_NE(fid, nullptr); \
1172885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    env_->SetStatic ## type ## Field(c, fid, value1); \
11732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(value1, env_->GetStatic ## type ## Field(c, fid)); \
1174885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    env_->SetStatic ## type ## Field(c, fid, value2); \
11752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(value2, env_->GetStatic ## type ## Field(c, fid)); \
11762d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    \
11772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CheckJniAbortCatcher jni_abort_catcher; \
11782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->GetStatic ## type ## Field(nullptr, fid); \
11792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("received null jclass"); \
11802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->SetStatic ## type ## Field(nullptr, fid, value1); \
11812d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("received null jclass"); \
11822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->GetStatic ## type ## Field(c, nullptr); \
11832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("fid == null"); \
11842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->SetStatic ## type ## Field(c, nullptr, value1); \
11852d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("fid == null"); \
1186885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  } while (false)
1187885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1188885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes#define EXPECT_PRIMITIVE_FIELD(instance, type, field_name, sig, value1, value2) \
1189885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  do { \
1190885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    jfieldID fid = env_->GetFieldID(c, field_name, sig); \
11912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_NE(fid, nullptr); \
1192885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    env_->Set ## type ## Field(instance, fid, value1); \
11932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(value1, env_->Get ## type ## Field(instance, fid)); \
1194885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    env_->Set ## type ## Field(instance, fid, value2); \
11952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(value2, env_->Get ## type ## Field(instance, fid)); \
11962d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    \
11972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CheckJniAbortCatcher jni_abort_catcher; \
11982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->Get ## type ## Field(nullptr, fid); \
11992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("obj == null"); \
12002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->Set ## type ## Field(nullptr, fid, value1); \
12012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("obj == null"); \
12022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->Get ## type ## Field(instance, nullptr); \
12032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("fid == null"); \
12042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->Set ## type ## Field(instance, nullptr, value1); \
12052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("fid == null"); \
1206885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  } while (false)
1207885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1208885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1209885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott HughesTEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) {
1210ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  TEST_DISABLED_FOR_PORTABLE();
121100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Thread::Current()->TransitionFromSuspendedToRunnable();
121200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  LoadDex("AllFields");
1213bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom  bool started = runtime_->Start();
12142d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(started);
1215885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1216885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jclass c = env_->FindClass("AllFields");
12172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
1218885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jobject o = env_->AllocObject(c);
12192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
1220885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
12212d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(Boolean, "sZ", "Z", JNI_TRUE, JNI_FALSE);
1222885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  EXPECT_STATIC_PRIMITIVE_FIELD(Byte, "sB", "B", 1, 2);
1223885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  EXPECT_STATIC_PRIMITIVE_FIELD(Char, "sC", "C", 'a', 'b');
1224885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  EXPECT_STATIC_PRIMITIVE_FIELD(Double, "sD", "D", 1.0, 2.0);
1225885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  EXPECT_STATIC_PRIMITIVE_FIELD(Float, "sF", "F", 1.0, 2.0);
1226885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  EXPECT_STATIC_PRIMITIVE_FIELD(Int, "sI", "I", 1, 2);
1227885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  EXPECT_STATIC_PRIMITIVE_FIELD(Long, "sJ", "J", 1, 2);
1228885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  EXPECT_STATIC_PRIMITIVE_FIELD(Short, "sS", "S", 1, 2);
1229885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
12302d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_PRIMITIVE_FIELD(o, Boolean, "iZ", "Z", JNI_TRUE, JNI_FALSE);
1231885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  EXPECT_PRIMITIVE_FIELD(o, Byte, "iB", "B", 1, 2);
1232885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  EXPECT_PRIMITIVE_FIELD(o, Char, "iC", "C", 'a', 'b');
1233885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  EXPECT_PRIMITIVE_FIELD(o, Double, "iD", "D", 1.0, 2.0);
1234885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  EXPECT_PRIMITIVE_FIELD(o, Float, "iF", "F", 1.0, 2.0);
1235885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  EXPECT_PRIMITIVE_FIELD(o, Int, "iI", "I", 1, 2);
1236885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  EXPECT_PRIMITIVE_FIELD(o, Long, "iJ", "J", 1, 2);
1237885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  EXPECT_PRIMITIVE_FIELD(o, Short, "iS", "S", 1, 2);
1238885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes}
1239885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1240885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott HughesTEST_F(JniInternalTest, GetObjectField_SetObjectField) {
1241ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  TEST_DISABLED_FOR_PORTABLE();
124200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Thread::Current()->TransitionFromSuspendedToRunnable();
124300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  LoadDex("AllFields");
124425c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom  runtime_->Start();
1245885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1246885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jclass c = env_->FindClass("AllFields");
12472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
1248885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jobject o = env_->AllocObject(c);
12492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
1250885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1251885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jstring s1 = env_->NewStringUTF("hello");
12522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s1, nullptr);
1253885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jstring s2 = env_->NewStringUTF("world");
12542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s2, nullptr);
1255885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1256885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;");
12572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s_fid, nullptr);
1258885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;");
12592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(i_fid, nullptr);
1260885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1261885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  env_->SetStaticObjectField(c, s_fid, s1);
1262885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid)));
1263885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  env_->SetStaticObjectField(c, s_fid, s2);
1264885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid)));
1265885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1266885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  env_->SetObjectField(o, i_fid, s1);
1267885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid)));
1268885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  env_->SetObjectField(o, i_fid, s2);
1269885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid)));
1270885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes}
1271885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
12722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, NewLocalRef_nullptr) {
12732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->NewLocalRef(nullptr), nullptr);
127418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
127518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
127618c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, NewLocalRef) {
127718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
12782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
127918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewLocalRef(s);
12802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, nullptr);
12812d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, s);
128218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
12832ced6a534157d5d963693346904389c19775d2daElliott Hughes  EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(o));
128418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
128518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
12862d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, DeleteLocalRef_nullptr) {
12872d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->DeleteLocalRef(nullptr);
128818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
128918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
129018c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, DeleteLocalRef) {
129118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
12922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
129318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteLocalRef(s);
129418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
12953f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes  // Currently, deleting an already-deleted reference is just a CheckJNI warning.
1296b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  {
1297b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    CheckJniAbortCatcher check_jni_abort_catcher;
1298b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    env_->DeleteLocalRef(s);
1299a9137c6bbdf4a1883f7b3f836c269eeb2ff619b2Elliott Hughes
1300ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    std::string expected(StringPrintf("native code passing in reference to "
1301ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                                      "invalid local reference: %p", s));
1302a9137c6bbdf4a1883f7b3f836c269eeb2ff619b2Elliott Hughes    check_jni_abort_catcher.Check(expected.c_str());
1303b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
130418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
130518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  s = env_->NewStringUTF("");
13062d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
130718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewLocalRef(s);
13082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
130918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
131018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteLocalRef(s);
131118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteLocalRef(o);
131218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
131318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
1314aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott HughesTEST_F(JniInternalTest, PushLocalFrame_10395422) {
1315aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // The JNI specification is ambiguous about whether the given capacity is to be interpreted as a
1316aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // maximum or as a minimum, but it seems like it's supposed to be a minimum, and that's how
1317aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // Android historically treated it, and it's how the RI treats it. It's also the more useful
1318aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // interpretation!
1319aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  ASSERT_EQ(JNI_OK, env_->PushLocalFrame(0));
13202d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->PopLocalFrame(nullptr);
1321aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes
1322aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // Negative capacities are not allowed.
1323aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(-1));
1324aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes
1325aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // And it's okay to have an upper limit. Ours is currently 512.
1326aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(8192));
1327aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes}
1328aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes
13292ced6a534157d5d963693346904389c19775d2daElliott HughesTEST_F(JniInternalTest, PushLocalFrame_PopLocalFrame) {
13302ced6a534157d5d963693346904389c19775d2daElliott Hughes  jobject original = env_->NewStringUTF("");
13312d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(original, nullptr);
13322ced6a534157d5d963693346904389c19775d2daElliott Hughes
13332ced6a534157d5d963693346904389c19775d2daElliott Hughes  jobject outer;
13342ced6a534157d5d963693346904389c19775d2daElliott Hughes  jobject inner1, inner2;
133500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(env_);
13362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Object* inner2_direct_pointer;
13372ced6a534157d5d963693346904389c19775d2daElliott Hughes  {
1338aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes    ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
13392ced6a534157d5d963693346904389c19775d2daElliott Hughes    outer = env_->NewLocalRef(original);
13402ced6a534157d5d963693346904389c19775d2daElliott Hughes
13412ced6a534157d5d963693346904389c19775d2daElliott Hughes    {
1342aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes      ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
13432ced6a534157d5d963693346904389c19775d2daElliott Hughes      inner1 = env_->NewLocalRef(outer);
13442ced6a534157d5d963693346904389c19775d2daElliott Hughes      inner2 = env_->NewStringUTF("survivor");
13452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      inner2_direct_pointer = soa.Decode<mirror::Object*>(inner2);
13462ced6a534157d5d963693346904389c19775d2daElliott Hughes      env_->PopLocalFrame(inner2);
13472ced6a534157d5d963693346904389c19775d2daElliott Hughes    }
13482ced6a534157d5d963693346904389c19775d2daElliott Hughes
13492ced6a534157d5d963693346904389c19775d2daElliott Hughes    EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
13502ced6a534157d5d963693346904389c19775d2daElliott Hughes    EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(outer));
13512ced6a534157d5d963693346904389c19775d2daElliott Hughes    EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
13522ced6a534157d5d963693346904389c19775d2daElliott Hughes
13532ced6a534157d5d963693346904389c19775d2daElliott Hughes    // Our local reference for the survivor is invalid because the survivor
13542ced6a534157d5d963693346904389c19775d2daElliott Hughes    // gets a new local reference...
13552ced6a534157d5d963693346904389c19775d2daElliott Hughes    EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
13562ced6a534157d5d963693346904389c19775d2daElliott Hughes
13572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->PopLocalFrame(nullptr);
13582ced6a534157d5d963693346904389c19775d2daElliott Hughes  }
13592ced6a534157d5d963693346904389c19775d2daElliott Hughes  EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
13602ced6a534157d5d963693346904389c19775d2daElliott Hughes  EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(outer));
13612ced6a534157d5d963693346904389c19775d2daElliott Hughes  EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
13622ced6a534157d5d963693346904389c19775d2daElliott Hughes  EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
13632ced6a534157d5d963693346904389c19775d2daElliott Hughes}
13642ced6a534157d5d963693346904389c19775d2daElliott Hughes
13652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, NewGlobalRef_nullptr) {
13662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->NewGlobalRef(nullptr), nullptr);
136718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
136818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
136918c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, NewGlobalRef) {
137018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
13712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
137218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewGlobalRef(s);
13732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, nullptr);
13742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, s);
137518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
13762d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetObjectRefType(o), JNIGlobalRefType);
137718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
137818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
13792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, DeleteGlobalRef_nullptr) {
13802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->DeleteGlobalRef(nullptr);
138118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
138218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
138318c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, DeleteGlobalRef) {
138418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
13852d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
138618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
138718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewGlobalRef(s);
13882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
138918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteGlobalRef(o);
139018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
13913f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes  // Currently, deleting an already-deleted reference is just a CheckJNI warning.
1392b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  {
1393b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    CheckJniAbortCatcher check_jni_abort_catcher;
1394b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    env_->DeleteGlobalRef(o);
1395a9137c6bbdf4a1883f7b3f836c269eeb2ff619b2Elliott Hughes
1396ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    std::string expected(StringPrintf("native code passing in reference to "
1397ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                                      "invalid global reference: %p", o));
1398a9137c6bbdf4a1883f7b3f836c269eeb2ff619b2Elliott Hughes    check_jni_abort_catcher.Check(expected.c_str());
1399b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
140018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
140118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o1 = env_->NewGlobalRef(s);
14022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o1, nullptr);
140318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o2 = env_->NewGlobalRef(s);
14042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o2, nullptr);
140518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
140618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteGlobalRef(o1);
140718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteGlobalRef(o2);
140818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
140918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
14102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, NewWeakGlobalRef_nullptr) {
14112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->NewWeakGlobalRef(nullptr),   nullptr);
141218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
141318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
141418c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, NewWeakGlobalRef) {
141518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
14162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
141718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewWeakGlobalRef(s);
14182d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, nullptr);
14192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, s);
142018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
14212d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetObjectRefType(o), JNIWeakGlobalRefType);
142218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
142318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
14242d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, DeleteWeakGlobalRef_nullptr) {
14252d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->DeleteWeakGlobalRef(nullptr);
142618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
142718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
142818c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, DeleteWeakGlobalRef) {
142918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
14302d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
143118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
143218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewWeakGlobalRef(s);
14332d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
143418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteWeakGlobalRef(o);
143518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
14363f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes  // Currently, deleting an already-deleted reference is just a CheckJNI warning.
1437b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  {
1438b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    CheckJniAbortCatcher check_jni_abort_catcher;
1439b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    env_->DeleteWeakGlobalRef(o);
1440a9137c6bbdf4a1883f7b3f836c269eeb2ff619b2Elliott Hughes
1441ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    std::string expected(StringPrintf("native code passing in reference to "
1442ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                                      "invalid weak global reference: %p", o));
1443a9137c6bbdf4a1883f7b3f836c269eeb2ff619b2Elliott Hughes    check_jni_abort_catcher.Check(expected.c_str());
1444b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
144518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
144618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o1 = env_->NewWeakGlobalRef(s);
14472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o1, nullptr);
144818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o2 = env_->NewWeakGlobalRef(s);
14492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o2, nullptr);
145018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
145118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteWeakGlobalRef(o1);
145218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteWeakGlobalRef(o2);
145318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
145418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
145537f7a40f6789bb287f287a9af00777af9d6428eeElliott HughesTEST_F(JniInternalTest, Throw) {
14562d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(JNI_ERR, env_->Throw(nullptr));
145737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
145837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass exception_class = env_->FindClass("java/lang/RuntimeException");
14592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(exception_class != nullptr);
146037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class));
14612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(exception != nullptr);
146237f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
146337f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  EXPECT_EQ(JNI_OK, env_->Throw(exception));
146437f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  EXPECT_TRUE(env_->ExceptionCheck());
1465a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes  jthrowable thrown_exception = env_->ExceptionOccurred();
146637f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  env_->ExceptionClear();
1467a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes  EXPECT_TRUE(env_->IsSameObject(exception, thrown_exception));
146837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes}
146937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
147037f7a40f6789bb287f287a9af00777af9d6428eeElliott HughesTEST_F(JniInternalTest, ThrowNew) {
14712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(JNI_ERR, env_->Throw(nullptr));
147237f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
147337f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass exception_class = env_->FindClass("java/lang/RuntimeException");
14742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(exception_class != nullptr);
147537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
14765cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  jthrowable thrown_exception;
14775cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes
147837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
147937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  EXPECT_TRUE(env_->ExceptionCheck());
14805cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  thrown_exception = env_->ExceptionOccurred();
14815cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  env_->ExceptionClear();
14825cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
14835cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes
14842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, nullptr));
14855cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  EXPECT_TRUE(env_->ExceptionCheck());
14865cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  thrown_exception = env_->ExceptionOccurred();
148737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  env_->ExceptionClear();
1488a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
148937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes}
149037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
14911d99e4549309d05007d041d058b1878de88e9585Ian RogersTEST_F(JniInternalTest, NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) {
14921d99e4549309d05007d041d058b1878de88e9585Ian Rogers  // Start runtime.
14931d99e4549309d05007d041d058b1878de88e9585Ian Rogers  Thread* self = Thread::Current();
14941d99e4549309d05007d041d058b1878de88e9585Ian Rogers  self->TransitionFromSuspendedToRunnable();
14951d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.lang.Class");
14961d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.lang.Object");
14971d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.DirectByteBuffer");
14981d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.MemoryBlock");
14991d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.MemoryBlock$UnmanagedBlock");
15001d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.MappedByteBuffer");
15011d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.ByteBuffer");
15021d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.Buffer");
15031d99e4549309d05007d041d058b1878de88e9585Ian Rogers  // TODO: we only load a dex file here as starting the runtime relies upon it.
15041d99e4549309d05007d041d058b1878de88e9585Ian Rogers  const char* class_name = "StaticLeafMethods";
15051d99e4549309d05007d041d058b1878de88e9585Ian Rogers  LoadDex(class_name);
15061d99e4549309d05007d041d058b1878de88e9585Ian Rogers  bool started = runtime_->Start();
15071d99e4549309d05007d041d058b1878de88e9585Ian Rogers  ASSERT_TRUE(started);
15081d99e4549309d05007d041d058b1878de88e9585Ian Rogers
1509b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jclass buffer_class = env_->FindClass("java/nio/Buffer");
15102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(buffer_class, nullptr);
1511b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1512b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  char bytes[1024];
1513b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes));
15142d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(buffer, nullptr);
1515b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class));
15162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_EQ(env_->GetDirectBufferAddress(buffer), bytes);
15171ee99352d85a07558688365dba70e9aa8f476c03Ian Rogers  ASSERT_EQ(env_->GetDirectBufferCapacity(buffer), static_cast<jlong>(sizeof(bytes)));
151845d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom
151945d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom  {
152045d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom    CheckJniAbortCatcher check_jni_abort_catcher;
152185a93364e5111dc56a73eed0130856e66cab0802Brian Carlstrom    env_->NewDirectByteBuffer(bytes, static_cast<jlong>(INT_MAX) + 1);
152245d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom    check_jni_abort_catcher.Check("in call to NewDirectByteBuffer");
152345d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom  }
1524b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes}
1525b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
15266d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian RogersTEST_F(JniInternalTest, MonitorEnterExit) {
15272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Create an object to torture.
15286d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  jclass object_class = env_->FindClass("java/lang/Object");
15292d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(object_class, nullptr);
15306d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  jobject object = env_->AllocObject(object_class);
15312d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(object, nullptr);
15326d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
15336d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Expected class of exceptions
15346d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  jclass imse_class = env_->FindClass("java/lang/IllegalMonitorStateException");
15352d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(imse_class, nullptr);
15366d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
15376d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  jthrowable thrown_exception;
15386d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
15396d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Unlock of unowned monitor
15406d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->MonitorExit(object);
15416d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_TRUE(env_->ExceptionCheck());
15426d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  thrown_exception = env_->ExceptionOccurred();
15436d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->ExceptionClear();
15446d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
15456d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
15466d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Lock of unowned monitor
15476d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->MonitorEnter(object);
15486d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
15496d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Regular unlock
15506d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->MonitorExit(object);
15516d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
15526d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
15536d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Recursively lock a lot
15546d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  size_t max_recursive_lock = 1024;
15556d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  for (size_t i = 0; i < max_recursive_lock; i++) {
15566d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    env_->MonitorEnter(object);
15576d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    EXPECT_FALSE(env_->ExceptionCheck());
15586d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  }
15596d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Recursively unlock a lot
15606d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  for (size_t i = 0; i < max_recursive_lock; i++) {
15616d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    env_->MonitorExit(object);
15626d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    EXPECT_FALSE(env_->ExceptionCheck());
15636d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  }
15646d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
15656d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Unlock of unowned monitor
15666d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->MonitorExit(object);
15676d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_TRUE(env_->ExceptionCheck());
15686d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  thrown_exception = env_->ExceptionOccurred();
15696d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->ExceptionClear();
15706d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
1571a92853eb60fbce1fa6d3bbd6a6013fb514fdf5cbElliott Hughes
15722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // It's an error to call MonitorEnter or MonitorExit on nullptr.
1573b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  {
1574b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    CheckJniAbortCatcher check_jni_abort_catcher;
15752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->MonitorEnter(nullptr);
1576b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    check_jni_abort_catcher.Check("in call to MonitorEnter");
15772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->MonitorExit(nullptr);
1578b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    check_jni_abort_catcher.Check("in call to MonitorExit");
1579b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
15806d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers}
15816d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
15824d5714378c3433ba7e351cbf6a6713fb49c31784Brian CarlstromTEST_F(JniInternalTest, DetachCurrentThread) {
15834d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom  CleanUpJniEnv();  // cleanup now so TearDown won't have junk from wrong JNIEnv
15844d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom  jint ok = vm_->DetachCurrentThread();
15854d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom  EXPECT_EQ(JNI_OK, ok);
15864d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom
15874d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom  jint err = vm_->DetachCurrentThread();
15884d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom  EXPECT_EQ(JNI_ERR, err);
15892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  vm_->AttachCurrentThread(&env_, nullptr);  // need attached thread for CommonRuntimeTest::TearDown
15904d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom}
15914d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom
15920cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers}  // namespace art
1593