jni_internal_test.cc revision 2f022bd02badb6a3b3edd5b65416a4235c665ccc
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"
2068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers#include "java_vm_ext.h"
21ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#include "mirror/art_method-inl.h"
2256890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih#include "mirror/string-inl.h"
23e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "scoped_thread_state_change.h"
24726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes#include "ScopedLocalRef.h"
250c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes
260c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughesnamespace art {
270c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes
28a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom// TODO: Convert to CommonRuntimeTest. Currently MakeExecutable is used.
29a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromclass JniInternalTest : public CommonCompilerTest {
30c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott Hughes protected:
31c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott Hughes  virtual void SetUp() {
32a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    CommonCompilerTest::SetUp();
335174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
34a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes    vm_ = Runtime::Current()->GetJavaVM();
35a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes
365174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes    // Turn on -verbose:jni for the JNI tests.
37797136386d6c66289ba1d12cbf5b2ac32646bb90Ian Rogers    // gLogVerbosity.jni = true;
385174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
392d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    vm_->AttachCurrentThread(&env_, nullptr);
40b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
41ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    ScopedLocalRef<jclass> aioobe(env_,
42ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                                  env_->FindClass("java/lang/ArrayIndexOutOfBoundsException"));
432d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK(aioobe.get() != nullptr);
44726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes    aioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(aioobe.get()));
45b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
46b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    ScopedLocalRef<jclass> ase(env_, env_->FindClass("java/lang/ArrayStoreException"));
472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK(ase.get() != nullptr);
48b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    ase_ = reinterpret_cast<jclass>(env_->NewGlobalRef(ase.get()));
49b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
50ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    ScopedLocalRef<jclass> sioobe(env_,
51ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                                  env_->FindClass("java/lang/StringIndexOutOfBoundsException"));
522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK(sioobe.get() != nullptr);
53726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes    sioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(sioobe.get()));
54726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes  }
55726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes
562d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  void ExpectException(jclass exception_class) {
5768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ScopedObjectAccess soa(env_);
5868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_TRUE(env_->ExceptionCheck())
5968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        << PrettyDescriptor(soa.Decode<mirror::Class*>(exception_class));
602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jthrowable exception = env_->ExceptionOccurred();
612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_NE(nullptr, exception);
622d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->ExceptionClear();
632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class));
642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  }
652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
664d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom  void CleanUpJniEnv() {
672d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (aioobe_ != nullptr) {
684d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom      env_->DeleteGlobalRef(aioobe_);
692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      aioobe_ = nullptr;
704d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom    }
712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (ase_ != nullptr) {
724d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom      env_->DeleteGlobalRef(ase_);
732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      ase_ = nullptr;
744d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom    }
752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (sioobe_ != nullptr) {
764d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom      env_->DeleteGlobalRef(sioobe_);
772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      sioobe_ = nullptr;
784d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom    }
794d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom  }
804d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom
8153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers  virtual void TearDown() OVERRIDE {
824d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom    CleanUpJniEnv();
83a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    CommonCompilerTest::TearDown();
84c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott Hughes  }
85b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
861d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jclass GetPrimitiveClass(char descriptor) {
871d99e4549309d05007d041d058b1878de88e9585Ian Rogers    ScopedObjectAccess soa(env_);
881d99e4549309d05007d041d058b1878de88e9585Ian Rogers    mirror::Class* c = class_linker_->FindPrimitiveClass(descriptor);
891d99e4549309d05007d041d058b1878de88e9585Ian Rogers    CHECK(c != nullptr);
901d99e4549309d05007d041d058b1878de88e9585Ian Rogers    return soa.AddLocalReference<jclass>(c);
911d99e4549309d05007d041d058b1878de88e9585Ian Rogers  }
921d99e4549309d05007d041d058b1878de88e9585Ian Rogers
9368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void ExpectClassFound(const char* name) {
9468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_NE(env_->FindClass(name), nullptr) << name;
9568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_FALSE(env_->ExceptionCheck()) << name;
9668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
9768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
9868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void ExpectClassNotFound(const char* name, bool check_jni, const char* check_jni_msg,
9968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                           CheckJniAbortCatcher* abort_catcher) {
10068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->FindClass(name), nullptr) << name;
10168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    if (!check_jni || check_jni_msg == nullptr) {
10268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_TRUE(env_->ExceptionCheck()) << name;
10368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      env_->ExceptionClear();
10468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    } else {
10568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      abort_catcher->Check(check_jni_msg);
10668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    }
10768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
10868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
10968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void FindClassTest(bool check_jni) {
11068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
11168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher check_jni_abort_catcher;
11268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
11368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // Null argument is always an abort.
11468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->FindClass(nullptr);
11568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
11668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "name == null");
11768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
11868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // Reference types...
11968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassFound("java/lang/String");
12068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // ...for arrays too, where you must include "L;".
12168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassFound("[Ljava/lang/String;");
12268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // Primitive arrays are okay too, if the primitive type is valid.
12368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassFound("[C");
12468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
12568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // But primitive types aren't allowed...
12668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassNotFound("C", check_jni, nullptr, &check_jni_abort_catcher);
12768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassNotFound("V", check_jni, nullptr, &check_jni_abort_catcher);
12868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassNotFound("K", check_jni, nullptr, &check_jni_abort_catcher);
12968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
13068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    if (check_jni) {
13168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      // Check JNI will reject invalid class names as aborts but without pending exceptions.
13268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_EQ(env_->FindClass("java.lang.String"), nullptr);
13368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_FALSE(env_->ExceptionCheck());
13468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      check_jni_abort_catcher.Check("illegal class name 'java.lang.String'");
13568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
13668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_EQ(env_->FindClass("[Ljava.lang.String;"), nullptr);
13768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_FALSE(env_->ExceptionCheck());
13868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      check_jni_abort_catcher.Check("illegal class name '[Ljava.lang.String;'");
13968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    } else {
14068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      // Without check JNI we're tolerant and replace '.' with '/'.
14168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      ExpectClassFound("java.lang.String");
14268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      ExpectClassFound("[Ljava.lang.String;");
14368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    }
14468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
14568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassNotFound("Ljava.lang.String;", check_jni, "illegal class name 'Ljava.lang.String;'",
14668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                        &check_jni_abort_catcher);
14768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassNotFound("[java.lang.String", check_jni, "illegal class name '[java.lang.String'",
14868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                        &check_jni_abort_catcher);
14968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
15068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // You can't include the "L;" in a JNI class descriptor.
15168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassNotFound("Ljava/lang/String;", check_jni, "illegal class name 'Ljava/lang/String;'",
15268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                        &check_jni_abort_catcher);
15368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
15468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // But you must include it for an array of any reference type.
15568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassNotFound("[java/lang/String", check_jni, "illegal class name '[java/lang/String'",
15668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                        &check_jni_abort_catcher);
15768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
15868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassNotFound("[K", check_jni, "illegal class name '[K'", &check_jni_abort_catcher);
15968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
16068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // Void arrays aren't allowed.
16168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassNotFound("[V", check_jni, "illegal class name '[V'", &check_jni_abort_catcher);
16268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
16368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
16468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
16568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
16668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void GetFieldIdBadArgumentTest(bool check_jni) {
16768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
16868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher check_jni_abort_catcher;
16968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
17068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass c = env_->FindClass("java/lang/String");
17168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_NE(c, nullptr);
17268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
17368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jfieldID fid = env_->GetFieldID(nullptr, "count", "I");
17468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, fid);
17568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "GetFieldID received NULL jclass"
17668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "java_class == null");
17768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    fid = env_->GetFieldID(c, nullptr, "I");
17868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, fid);
17968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
18068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "name == null");
18168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    fid = env_->GetFieldID(c, "count", nullptr);
18268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, fid);
18368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
18468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "sig == null");
18568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
18668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
18768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
18868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
18968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void GetStaticFieldIdBadArgumentTest(bool check_jni) {
19068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
19168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher check_jni_abort_catcher;
19268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
19368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass c = env_->FindClass("java/lang/String");
19468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_NE(c, nullptr);
19568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
19668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jfieldID fid = env_->GetStaticFieldID(nullptr, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
19768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, fid);
19868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "GetStaticFieldID received NULL jclass"
19968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "java_class == null");
20068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    fid = env_->GetStaticFieldID(c, nullptr, "Ljava/util/Comparator;");
20168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, fid);
20268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
20368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "name == null");
20468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", nullptr);
20568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, fid);
20668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
20768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "sig == null");
20868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
20968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
21068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
21168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
21268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void GetMethodIdBadArgumentTest(bool check_jni) {
21368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
21468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher check_jni_abort_catcher;
21568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
21668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jmethodID method = env_->GetMethodID(nullptr, "<init>", "(Ljava/lang/String;)V");
21768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, method);
21868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "GetMethodID received NULL jclass"
21968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "java_class == null");
22068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
22168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_TRUE(jlnsme != nullptr);
22268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    method = env_->GetMethodID(jlnsme, nullptr, "(Ljava/lang/String;)V");
22368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, method);
22468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
22568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "name == null");
22668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    method = env_->GetMethodID(jlnsme, "<init>", nullptr);
22768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, method);
22868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
22968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "sig == null");
23068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
23168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
23268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
23368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
23468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void GetStaticMethodIdBadArgumentTest(bool check_jni) {
23568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
23668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher check_jni_abort_catcher;
23768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
23868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jmethodID method = env_->GetStaticMethodID(nullptr, "valueOf", "(I)Ljava/lang/String;");
23968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, method);
24068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "GetStaticMethodID received NULL jclass"
24168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "java_class == null");
24268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass jlstring = env_->FindClass("java/lang/String");
24368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    method = env_->GetStaticMethodID(jlstring, nullptr, "(I)Ljava/lang/String;");
24468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, method);
24568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
24668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "name == null");
24768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    method = env_->GetStaticMethodID(jlstring, "valueOf", nullptr);
24868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, method);
24968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
25068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "sig == null");
25168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
25268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
25368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
25468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
25568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void GetFromReflectedField_ToReflectedFieldBadArgumentTest(bool check_jni) {
25668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
25768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher check_jni_abort_catcher;
25868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
25968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass c = env_->FindClass("java/lang/String");
26068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_NE(c, nullptr);
26168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jfieldID fid = env_->GetFieldID(c, "count", "I");
26268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_NE(fid, nullptr);
26368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
26468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // Check class argument for null argument, not checked in non-check JNI.
26568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jobject field = env_->ToReflectedField(nullptr, fid, JNI_FALSE);
26668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    if (check_jni) {
26768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_EQ(field, nullptr);
26868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      check_jni_abort_catcher.Check("ToReflectedField received NULL jclass");
26968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    } else {
27068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_NE(field, nullptr);
27168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    }
27268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
27368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    field = env_->ToReflectedField(c, nullptr, JNI_FALSE);
27468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(field, nullptr);
27568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "jfieldID was NULL"
27668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "fid == null");
27768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
27868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    fid = env_->FromReflectedField(nullptr);
27968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_EQ(fid, nullptr);
28068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "expected non-null java.lang.reflect.Field"
28168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "jlr_field == null");
28268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
28368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
28468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
28568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
28668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void GetFromReflectedMethod_ToReflectedMethodBadArgumentTest(bool check_jni) {
28768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
28868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher check_jni_abort_catcher;
28968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
29068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass c = env_->FindClass("java/lang/String");
29168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_NE(c, nullptr);
29268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jmethodID mid = env_->GetMethodID(c, "<init>", "()V");
29368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_NE(mid, nullptr);
29468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
29568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // Check class argument for null argument, not checked in non-check JNI.
29668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jobject method = env_->ToReflectedMethod(nullptr, mid, JNI_FALSE);
29768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    if (check_jni) {
29868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_EQ(method, nullptr);
29968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      check_jni_abort_catcher.Check("ToReflectedMethod received NULL jclass");
30068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    } else {
30168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_NE(method, nullptr);
30268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    }
30368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
30468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    method = env_->ToReflectedMethod(c, nullptr, JNI_FALSE);
30568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(method, nullptr);
30668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "jmethodID was NULL"
30768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "mid == null");
30868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    mid = env_->FromReflectedMethod(method);
30968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_EQ(mid, nullptr);
31068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "expected non-null method" : "jlr_method == null");
31168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
31268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
31368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
31468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
31568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void RegisterAndUnregisterNativesBadArguments(bool check_jni,
31668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                                CheckJniAbortCatcher* check_jni_abort_catcher) {
31768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
31868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // Passing a class of null is a failure.
31968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    {
32068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      JNINativeMethod methods[] = { };
32168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_EQ(env_->RegisterNatives(nullptr, methods, 0), JNI_ERR);
32268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      check_jni_abort_catcher->Check(check_jni ? "RegisterNatives received NULL jclass"
32368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                               : "java_class == null");
32468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    }
32568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
32668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // Passing methods as null is a failure.
32768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass jlobject = env_->FindClass("java/lang/Object");
32868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->RegisterNatives(jlobject, nullptr, 1), JNI_ERR);
32968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher->Check("methods == null");
33068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
33168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // Unregisters null is a failure.
33268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->UnregisterNatives(nullptr), JNI_ERR);
33368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher->Check(check_jni ? "UnregisterNatives received NULL jclass"
33468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                             : "java_class == null");
33568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
33668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
33768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
33868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
33968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
34068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void GetPrimitiveArrayElementsOfWrongType(bool check_jni) {
34168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
34268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher jni_abort_catcher;
34368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
34468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jbooleanArray array = env_->NewBooleanArray(10);
34568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jboolean is_copy;
34668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetByteArrayElements(reinterpret_cast<jbyteArray>(array), &is_copy), nullptr);
34768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
34868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected byte[]"
34968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get byte primitive array elements with an object of type boolean[]");
35068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetShortArrayElements(reinterpret_cast<jshortArray>(array), &is_copy), nullptr);
35168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
35268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected short[]"
35368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get short primitive array elements with an object of type boolean[]");
35468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetCharArrayElements(reinterpret_cast<jcharArray>(array), &is_copy), nullptr);
35568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
35668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected char[]"
35768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get char primitive array elements with an object of type boolean[]");
35868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetIntArrayElements(reinterpret_cast<jintArray>(array), &is_copy), nullptr);
35968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
36068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected int[]"
36168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get int primitive array elements with an object of type boolean[]");
36268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetLongArrayElements(reinterpret_cast<jlongArray>(array), &is_copy), nullptr);
36368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
36468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected long[]"
36568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get long primitive array elements with an object of type boolean[]");
36668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetFloatArrayElements(reinterpret_cast<jfloatArray>(array), &is_copy), nullptr);
36768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
36868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected float[]"
36968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get float primitive array elements with an object of type boolean[]");
37068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetDoubleArrayElements(reinterpret_cast<jdoubleArray>(array), &is_copy), nullptr);
37168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
37268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected double[]"
37368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get double primitive array elements with an object of type boolean[]");
37468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jbyteArray array2 = env_->NewByteArray(10);
37568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetBooleanArrayElements(reinterpret_cast<jbooleanArray>(array2), &is_copy),
37668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers              nullptr);
37768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
37868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type byte[] expected boolean[]"
37968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get boolean primitive array elements with an object of type byte[]");
38068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jobject object = env_->NewStringUTF("Test String");
38168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetBooleanArrayElements(reinterpret_cast<jbooleanArray>(object), &is_copy),
38268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers              nullptr);
38368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
38468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "jarray argument has non-array type: java.lang.String"
38568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        : "attempt to get boolean primitive array elements with an object of type java.lang.String");
38668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
38768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
38868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
38968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
39068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void ReleasePrimitiveArrayElementsOfWrongType(bool check_jni) {
39168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
39268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher jni_abort_catcher;
39368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
39468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jbooleanArray array = env_->NewBooleanArray(10);
39568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_TRUE(array != nullptr);
39668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jboolean is_copy;
39768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jboolean* elements = env_->GetBooleanArrayElements(array, &is_copy);
39868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_TRUE(elements != nullptr);
39968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->ReleaseByteArrayElements(reinterpret_cast<jbyteArray>(array),
40068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                   reinterpret_cast<jbyte*>(elements), 0);
40168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
40268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected byte[]"
40368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to release byte primitive array elements with an object of type boolean[]");
40468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->ReleaseShortArrayElements(reinterpret_cast<jshortArray>(array),
40568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                    reinterpret_cast<jshort*>(elements), 0);
40668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
40768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected short[]"
40868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to release short primitive array elements with an object of type boolean[]");
40968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->ReleaseCharArrayElements(reinterpret_cast<jcharArray>(array),
41068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                   reinterpret_cast<jchar*>(elements), 0);
41168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
41268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected char[]"
41368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to release char primitive array elements with an object of type boolean[]");
41468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->ReleaseIntArrayElements(reinterpret_cast<jintArray>(array),
41568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                  reinterpret_cast<jint*>(elements), 0);
41668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
41768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected int[]"
41868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to release int primitive array elements with an object of type boolean[]");
41968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->ReleaseLongArrayElements(reinterpret_cast<jlongArray>(array),
42068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                   reinterpret_cast<jlong*>(elements), 0);
42168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
42268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected long[]"
42368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to release long primitive array elements with an object of type boolean[]");
42468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->ReleaseFloatArrayElements(reinterpret_cast<jfloatArray>(array),
42568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                    reinterpret_cast<jfloat*>(elements), 0);
42668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
42768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected float[]"
42868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to release float primitive array elements with an object of type boolean[]");
42968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->ReleaseDoubleArrayElements(reinterpret_cast<jdoubleArray>(array),
43068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                     reinterpret_cast<jdouble*>(elements), 0);
43168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
43268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected double[]"
43368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to release double primitive array elements with an object of type boolean[]");
43468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jbyteArray array2 = env_->NewByteArray(10);
43568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->ReleaseBooleanArrayElements(reinterpret_cast<jbooleanArray>(array2), elements, 0);
43668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
43768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type byte[] expected boolean[]"
43868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to release boolean primitive array elements with an object of type byte[]");
43968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jobject object = env_->NewStringUTF("Test String");
44068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->ReleaseBooleanArrayElements(reinterpret_cast<jbooleanArray>(object), elements, 0);
44168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
44268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "jarray argument has non-array type: java.lang.String"
44368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to release boolean primitive array elements with an object of type "
44468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers              "java.lang.String");
44568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
44668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
44768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
44868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
44968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void GetReleasePrimitiveArrayCriticalOfWrongType(bool check_jni) {
45068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
45168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher jni_abort_catcher;
45268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
45368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jobject object = env_->NewStringUTF("Test String");
45468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jboolean is_copy;
45568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    void* elements = env_->GetPrimitiveArrayCritical(reinterpret_cast<jarray>(object), &is_copy);
45668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String"
45768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        : "expected primitive array, given java.lang.String");
45868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->ReleasePrimitiveArrayCritical(reinterpret_cast<jarray>(object), elements, 0);
45968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String"
46068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        : "expected primitive array, given java.lang.String");
46168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
46268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
46368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
46468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
46568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void GetPrimitiveArrayRegionElementsOfWrongType(bool check_jni) {
46668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
46768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher jni_abort_catcher;
46868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    constexpr size_t kLength = 10;
46968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jbooleanArray array = env_->NewBooleanArray(kLength);
47068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_TRUE(array != nullptr);
47168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jboolean elements[kLength];
47268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetByteArrayRegion(reinterpret_cast<jbyteArray>(array), 0, kLength,
47368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                             reinterpret_cast<jbyte*>(elements));
47468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
47568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected byte[]"
47668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get region of byte primitive array elements with an object of type boolean[]");
47768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetShortArrayRegion(reinterpret_cast<jshortArray>(array), 0, kLength,
47868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                              reinterpret_cast<jshort*>(elements));
47968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
48068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected short[]"
48168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get region of short primitive array elements with an object of type boolean[]");
48268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetCharArrayRegion(reinterpret_cast<jcharArray>(array), 0, kLength,
48368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                             reinterpret_cast<jchar*>(elements));
48468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
48568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected char[]"
48668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get region of char primitive array elements with an object of type boolean[]");
48768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetIntArrayRegion(reinterpret_cast<jintArray>(array), 0, kLength,
48868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                            reinterpret_cast<jint*>(elements));
48968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
49068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected int[]"
49168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get region of int primitive array elements with an object of type boolean[]");
49268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetLongArrayRegion(reinterpret_cast<jlongArray>(array), 0, kLength,
49368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                             reinterpret_cast<jlong*>(elements));
49468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
49568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected long[]"
49668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get region of long primitive array elements with an object of type boolean[]");
49768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetFloatArrayRegion(reinterpret_cast<jfloatArray>(array), 0, kLength,
49868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                              reinterpret_cast<jfloat*>(elements));
49968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
50068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected float[]"
50168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get region of float primitive array elements with an object of type boolean[]");
50268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetDoubleArrayRegion(reinterpret_cast<jdoubleArray>(array), 0, kLength,
50368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                               reinterpret_cast<jdouble*>(elements));
50468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
50568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected double[]"
50668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get region of double primitive array elements with an object of type boolean[]");
50768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jbyteArray array2 = env_->NewByteArray(10);
50868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(array2), 0, kLength,
50968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                reinterpret_cast<jboolean*>(elements));
51068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
51168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type byte[] expected boolean[]"
51268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get region of boolean primitive array elements with an object of type byte[]");
51368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jobject object = env_->NewStringUTF("Test String");
51468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(object), 0, kLength,
51568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                reinterpret_cast<jboolean*>(elements));
51668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String"
51768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        : "attempt to get region of boolean primitive array elements with an object of type "
51868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers          "java.lang.String");
51968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
52068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
52168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
52268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
52368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void SetPrimitiveArrayRegionElementsOfWrongType(bool check_jni) {
52468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
52568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher jni_abort_catcher;
52668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    constexpr size_t kLength = 10;
52768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jbooleanArray array = env_->NewBooleanArray(kLength);
52868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_TRUE(array != nullptr);
52968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jboolean elements[kLength];
53068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetByteArrayRegion(reinterpret_cast<jbyteArray>(array), 0, kLength,
53168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                             reinterpret_cast<jbyte*>(elements));
53268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
53368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected byte[]"
53468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to set region of byte primitive array elements with an object of type boolean[]");
53568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetShortArrayRegion(reinterpret_cast<jshortArray>(array), 0, kLength,
53668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                              reinterpret_cast<jshort*>(elements));
53768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
53868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected short[]"
53968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to set region of short primitive array elements with an object of type boolean[]");
54068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetCharArrayRegion(reinterpret_cast<jcharArray>(array), 0, kLength,
54168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                             reinterpret_cast<jchar*>(elements));
54268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
54368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected char[]"
54468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to set region of char primitive array elements with an object of type boolean[]");
54568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetIntArrayRegion(reinterpret_cast<jintArray>(array), 0, kLength,
54668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                            reinterpret_cast<jint*>(elements));
54768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
54868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected int[]"
54968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to set region of int primitive array elements with an object of type boolean[]");
55068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetLongArrayRegion(reinterpret_cast<jlongArray>(array), 0, kLength,
55168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                             reinterpret_cast<jlong*>(elements));
55268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
55368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected long[]"
55468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to set region of long primitive array elements with an object of type boolean[]");
55568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetFloatArrayRegion(reinterpret_cast<jfloatArray>(array), 0, kLength,
55668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                              reinterpret_cast<jfloat*>(elements));
55768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
55868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected float[]"
55968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to set region of float primitive array elements with an object of type boolean[]");
56068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetDoubleArrayRegion(reinterpret_cast<jdoubleArray>(array), 0, kLength,
56168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                               reinterpret_cast<jdouble*>(elements));
56268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
56368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected double[]"
56468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to set region of double primitive array elements with an object of type boolean[]");
56568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jbyteArray array2 = env_->NewByteArray(10);
56668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(array2), 0, kLength,
56768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                reinterpret_cast<jboolean*>(elements));
56868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
56968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type byte[] expected boolean[]"
57068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to set region of boolean primitive array elements with an object of type byte[]");
57168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jobject object = env_->NewStringUTF("Test String");
57268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(object), 0, kLength,
57368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                reinterpret_cast<jboolean*>(elements));
57468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String"
57568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        : "attempt to set region of boolean primitive array elements with an object of type "
57668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers          "java.lang.String");
57768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
57868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
57968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
58068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void NewObjectArrayBadArguments(bool check_jni) {
58168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
58268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher jni_abort_catcher;
58368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
58468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass element_class = env_->FindClass("java/lang/String");
58568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_NE(element_class, nullptr);
58668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
58768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->NewObjectArray(-1, element_class, nullptr);
58868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(check_jni ? "negative jsize: -1" : "negative array length: -1");
58968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
59068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->NewObjectArray(std::numeric_limits<jint>::min(), element_class, nullptr);
59168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(check_jni ? "negative jsize: -2147483648"
59268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        : "negative array length: -2147483648");
59368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
59468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
59568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
59668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
597a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes  JavaVMExt* vm_;
5984d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom  JNIEnv* env_;
599814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  jclass aioobe_;
600b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  jclass ase_;
601b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jclass sioobe_;
6020c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes};
6030c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes
604885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott HughesTEST_F(JniInternalTest, AllocObject) {
605885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jclass c = env_->FindClass("java/lang/String");
6062d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
607885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jobject o = env_->AllocObject(c);
6082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
609885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
610885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  // We have an instance of the class we asked for...
611885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsInstanceOf(o, c));
612885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  // ...whose fields haven't been initialized because
613885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  // we didn't call a constructor.
614885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "count", "I")));
615885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "offset", "I")));
6162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(env_->GetObjectField(o, env_->GetFieldID(c, "value", "[C")) == nullptr);
617885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes}
618885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
619c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott HughesTEST_F(JniInternalTest, GetVersion) {
620c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott Hughes  ASSERT_EQ(JNI_VERSION_1_6, env_->GetVersion());
621c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott Hughes}
622c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott Hughes
6230c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott HughesTEST_F(JniInternalTest, FindClass) {
62468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  FindClassTest(false);
62568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  FindClassTest(true);
6260c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes}
6270c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes
628cdf53120cd5a73cbedc1654e22542848468c0d2fElliott HughesTEST_F(JniInternalTest, GetFieldID) {
629cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
6302d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(jlnsfe, nullptr);
631cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass c = env_->FindClass("java/lang/String");
6322d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
633cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
634cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Wrong type.
635cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jfieldID fid = env_->GetFieldID(c, "count", "J");
6362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
6372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
638cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
639b17d08b6ef0d36038e408dd79960293bb62ec1d9Ian Rogers  // Wrong type where type doesn't exist.
640b17d08b6ef0d36038e408dd79960293bb62ec1d9Ian Rogers  fid = env_->GetFieldID(c, "count", "Lrod/jane/freddy;");
6412d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
6422d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
643b17d08b6ef0d36038e408dd79960293bb62ec1d9Ian Rogers
644cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Wrong name.
645cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetFieldID(c, "Count", "I");
6462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
6472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
648cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
649cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Good declared field lookup.
650cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetFieldID(c, "count", "I");
6512d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(nullptr, fid);
652cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  EXPECT_FALSE(env_->ExceptionCheck());
653cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
654cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Good superclass field lookup.
655cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  c = env_->FindClass("java/lang/StringBuilder");
656cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetFieldID(c, "count", "I");
6572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(nullptr, fid);
6582d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(fid, nullptr);
659cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  EXPECT_FALSE(env_->ExceptionCheck());
660cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
661cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Not instance.
662cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
6632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
6642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
6652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
6662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Bad arguments.
66768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetFieldIdBadArgumentTest(false);
66868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetFieldIdBadArgumentTest(true);
669cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes}
670cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
671cdf53120cd5a73cbedc1654e22542848468c0d2fElliott HughesTEST_F(JniInternalTest, GetStaticFieldID) {
672cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
6732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(jlnsfe, nullptr);
674cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass c = env_->FindClass("java/lang/String");
6752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
676cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
677cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Wrong type.
678cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J");
6792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
6802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
681cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
682b17d08b6ef0d36038e408dd79960293bb62ec1d9Ian Rogers  // Wrong type where type doesn't exist.
683b17d08b6ef0d36038e408dd79960293bb62ec1d9Ian Rogers  fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Lrod/jane/freddy;");
6842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
6852d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
686b17d08b6ef0d36038e408dd79960293bb62ec1d9Ian Rogers
687cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Wrong name.
688cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
6892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
6902d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
691cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
692cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Good declared field lookup.
693cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
6942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(nullptr, fid);
6952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(fid, nullptr);
696cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  EXPECT_FALSE(env_->ExceptionCheck());
697cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
698cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Not static.
699cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetStaticFieldID(c, "count", "I");
7002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
7012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
7022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
7032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Bad arguments.
70468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetStaticFieldIdBadArgumentTest(false);
70568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetStaticFieldIdBadArgumentTest(true);
706cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes}
707cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
7084dd71f1538a8d788c56c77378a59ce32afa519d7Ian RogersTEST_F(JniInternalTest, GetMethodID) {
7094dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlobject = env_->FindClass("java/lang/Object");
7104dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlstring = env_->FindClass("java/lang/String");
7114dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
712004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  jclass jncrbc = env_->FindClass("java/nio/channels/ReadableByteChannel");
7134dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
714004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  // Sanity check that no exceptions are pending.
715cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  ASSERT_FALSE(env_->ExceptionCheck());
7164dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
7174dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
718004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  // a pending exception.
7194dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jmethodID method = env_->GetMethodID(jlobject, "foo", "()V");
7202d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, method);
7212d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsme);
7224dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
723004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  // Check that java.lang.Object.equals() does exist.
7244dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
7252d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(nullptr, method);
7264dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
7274dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
7284dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // Check that GetMethodID for java.lang.String.valueOf(int) fails as the
729004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  // method is static.
7304dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
7312d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, method);
7322d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsme);
733ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom
734004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  // Check that GetMethodID for java.lang.NoSuchMethodError.<init>(String) finds the constructor.
735ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  method = env_->GetMethodID(jlnsme, "<init>", "(Ljava/lang/String;)V");
7362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(nullptr, method);
737ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_FALSE(env_->ExceptionCheck());
7382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
739004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  // Check that GetMethodID can find a interface method inherited from another interface.
740004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  method = env_->GetMethodID(jncrbc, "close", "()V");
741004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  EXPECT_NE(nullptr, method);
742004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  EXPECT_FALSE(env_->ExceptionCheck());
743004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom
7442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Bad arguments.
74568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetMethodIdBadArgumentTest(false);
74668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetMethodIdBadArgumentTest(true);
7474dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers}
7484dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
749a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu ChartierTEST_F(JniInternalTest, CallVoidMethodNullReceiver) {
750a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  jclass jlobject = env_->FindClass("java/lang/Object");
751a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  jmethodID method;
752a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier
753a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  // Check that GetMethodID for java.lang.NoSuchMethodError.<init>(String) finds the constructor.
754a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  method = env_->GetMethodID(jlobject, "<init>", "()V");
755a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  EXPECT_NE(nullptr, method);
756a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  EXPECT_FALSE(env_->ExceptionCheck());
757a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier
758a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  // Null object to CallVoidMethod.
759a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  CheckJniAbortCatcher check_jni_abort_catcher;
760a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  env_->CallVoidMethod(nullptr, method);
761a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  check_jni_abort_catcher.Check("null");
762a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier}
763a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier
7644dd71f1538a8d788c56c77378a59ce32afa519d7Ian RogersTEST_F(JniInternalTest, GetStaticMethodID) {
7654dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlobject = env_->FindClass("java/lang/Object");
7664dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
7674dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
7684dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // Sanity check that no exceptions are pending
769cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  ASSERT_FALSE(env_->ExceptionCheck());
7704dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
7714dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
7724dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // a pending exception
7734dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V");
7742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, method);
7752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsme);
7764dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
7774dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as
7784dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // the method is not static
7794dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
7802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, method);
7812d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsme);
7824dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
7834dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // Check that java.lang.String.valueOf(int) does exist
7844dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlstring = env_->FindClass("java/lang/String");
7852d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  method = env_->GetStaticMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
7862d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(nullptr, method);
7874dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
7882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
7892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Bad arguments.
79068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetStaticMethodIdBadArgumentTest(false);
79168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetStaticMethodIdBadArgumentTest(true);
7924dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers}
7934dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
794cdf53120cd5a73cbedc1654e22542848468c0d2fElliott HughesTEST_F(JniInternalTest, FromReflectedField_ToReflectedField) {
795cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass jlrField = env_->FindClass("java/lang/reflect/Field");
796cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass c = env_->FindClass("java/lang/String");
7972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
798cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jfieldID fid = env_->GetFieldID(c, "count", "I");
7992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(fid, nullptr);
800cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Turn the fid into a java.lang.reflect.Field...
801cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jobject field = env_->ToReflectedField(c, fid, JNI_FALSE);
8022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
803cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  ASSERT_TRUE(env_->IsInstanceOf(field, jlrField));
804cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // ...and back again.
805cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jfieldID fid2 = env_->FromReflectedField(field);
8062d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(fid2, nullptr);
807ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  // Make sure we can actually use it.
808ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  jstring s = env_->NewStringUTF("poop");
809ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  ASSERT_EQ(4, env_->GetIntField(s, fid2));
8102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
8112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Bad arguments.
81268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetFromReflectedField_ToReflectedFieldBadArgumentTest(false);
81368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetFromReflectedField_ToReflectedFieldBadArgumentTest(true);
814cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes}
815cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
816cdf53120cd5a73cbedc1654e22542848468c0d2fElliott HughesTEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
817cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass jlrMethod = env_->FindClass("java/lang/reflect/Method");
818d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(jlrMethod, nullptr);
819d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  jclass jlrConstructor = env_->FindClass("java/lang/reflect/Constructor");
820d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(jlrConstructor, nullptr);
821cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass c = env_->FindClass("java/lang/String");
8222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
823d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz
824d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  jmethodID mid = env_->GetMethodID(c, "<init>", "()V");
8252d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(mid, nullptr);
826d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  // Turn the mid into a java.lang.reflect.Constructor...
827cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
828d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(method, nullptr);
829d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_TRUE(env_->IsInstanceOf(method, jlrConstructor));
830cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // ...and back again.
831cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jmethodID mid2 = env_->FromReflectedMethod(method);
8322d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(mid2, nullptr);
833ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  // Make sure we can actually use it.
834d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  jstring s = reinterpret_cast<jstring>(env_->AllocObject(c));
835d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(s, nullptr);
836d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  env_->CallVoidMethod(s, mid2);
837d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_EQ(JNI_FALSE, env_->ExceptionCheck());
838d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz
839d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  mid = env_->GetMethodID(c, "length", "()I");
840d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(mid, nullptr);
841d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  // Turn the mid into a java.lang.reflect.Method...
842d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
843d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(method, nullptr);
844d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod));
845d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  // ...and back again.
846d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  mid2 = env_->FromReflectedMethod(method);
847d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(mid2, nullptr);
848d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  // Make sure we can actually use it.
849d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  s = env_->NewStringUTF("poop");
850d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(s, nullptr);
8515d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers  ASSERT_EQ(4, env_->CallIntMethod(s, mid2));
8522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
8532d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Bad arguments.
85468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetFromReflectedMethod_ToReflectedMethodBadArgumentTest(false);
85568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetFromReflectedMethod_ToReflectedMethodBadArgumentTest(true);
856cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes}
857cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
8582d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogersstatic void BogusMethod() {
8592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // You can't pass nullptr function pointers to RegisterNatives.
8605174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes}
8615174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
8622d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, RegisterAndUnregisterNatives) {
8634dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlobject = env_->FindClass("java/lang/Object");
8644dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
865fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  void* native_function = reinterpret_cast<void*>(BogusMethod);
8664dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
8672d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Sanity check that no exceptions are pending.
868cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  ASSERT_FALSE(env_->ExceptionCheck());
8694dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
870fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  // Check that registering method without name causes a NoSuchMethodError.
871fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  {
872fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz    JNINativeMethod methods[] = { { nullptr, "()V", native_function } };
873fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz    EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
874fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  }
875fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  ExpectException(jlnsme);
876fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz
877fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  // Check that registering method without signature causes a NoSuchMethodError.
878fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  {
879fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz    JNINativeMethod methods[] = { { "notify", nullptr, native_function } };
880fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz    EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
881fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  }
882fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  ExpectException(jlnsme);
883fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz
884fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  // Check that registering method without function causes a NoSuchMethodError.
885fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  {
886fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz    JNINativeMethod methods[] = { { "notify", "()V", nullptr } };
887fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz    EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
888fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  }
889fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  ExpectException(jlnsme);
890fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz
8912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Check that registering to a non-existent java.lang.Object.foo() causes a NoSuchMethodError.
8924dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  {
893fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz    JNINativeMethod methods[] = { { "foo", "()V", native_function } };
8942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
8954dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  }
8962d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsme);
8974dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
8982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Check that registering non-native methods causes a NoSuchMethodError.
8994dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  {
900fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz    JNINativeMethod methods[] = { { "equals", "(Ljava/lang/Object;)Z", native_function } };
9012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
9024dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  }
9032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsme);
9044dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
9052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Check that registering native methods is successful.
9064dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  {
907fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz    JNINativeMethod methods[] = { { "notify", "()V", native_function } };
9082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_OK);
9092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  }
9102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
9112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->UnregisterNatives(jlobject), JNI_OK);
9122d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
9132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Check that registering no methods isn't a failure.
9142d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  {
9152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    JNINativeMethod methods[] = { };
9162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 0), JNI_OK);
9172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  }
9182d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
9192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->UnregisterNatives(jlobject), JNI_OK);
9202d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
9212d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Check that registering a -ve number of methods is a failure.
9222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher check_jni_abort_catcher;
9232d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  for (int i = -10; i < 0; ++i) {
9242d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    JNINativeMethod methods[] = { };
9252d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->RegisterNatives(jlobject, methods, i), JNI_ERR);
9262d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    check_jni_abort_catcher.Check("negative method count: ");
9274dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  }
9284dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
9295174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
9302d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Unregistering a class with no natives is a warning.
9312d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->UnregisterNatives(jlnsme), JNI_OK);
93268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
93368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  RegisterAndUnregisterNativesBadArguments(false, &check_jni_abort_catcher);
93468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  RegisterAndUnregisterNativesBadArguments(true, &check_jni_abort_catcher);
9354dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers}
9364dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
937ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#define EXPECT_PRIMITIVE_ARRAY(new_fn, \
938ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               get_region_fn, \
939ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               set_region_fn, \
940ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               get_elements_fn, \
941ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               release_elements_fn, \
942ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               scalar_type, \
943ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               expected_class_descriptor) \
9442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jsize size = 4; \
9452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  \
9461d99e4549309d05007d041d058b1878de88e9585Ian Rogers  { \
9471d99e4549309d05007d041d058b1878de88e9585Ian Rogers    CheckJniAbortCatcher jni_abort_catcher; \
94868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    down_cast<JNIEnvExt*>(env_)->SetCheckJniEnabled(false); \
9491d99e4549309d05007d041d058b1878de88e9585Ian Rogers    /* Allocate an negative sized array and check it has the right failure type. */ \
9502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->new_fn(-1), nullptr); \
9511d99e4549309d05007d041d058b1878de88e9585Ian Rogers    jni_abort_catcher.Check("negative array length: -1"); \
9522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->new_fn(std::numeric_limits<jint>::min()), nullptr); \
9531d99e4549309d05007d041d058b1878de88e9585Ian Rogers    jni_abort_catcher.Check("negative array length: -2147483648"); \
9542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    /* Pass the array as null. */ \
9552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(0, env_->GetArrayLength(nullptr)); \
9562d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("java_array == null"); \
9572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->get_region_fn(nullptr, 0, 0, nullptr); \
9582d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("java_array == null"); \
9592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->set_region_fn(nullptr, 0, 0, nullptr); \
9602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("java_array == null"); \
9612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->get_elements_fn(nullptr, nullptr); \
9622d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("java_array == null"); \
9632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->release_elements_fn(nullptr, nullptr, 0); \
9642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("java_array == null"); \
9652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    /* Pass the elements for region as null. */ \
9662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    scalar_type ## Array a = env_->new_fn(size); \
9672d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->get_region_fn(a, 0, size, nullptr); \
9682d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("buf == null"); \
9692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->set_region_fn(a, 0, size, nullptr); \
9702d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("buf == null"); \
97168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    down_cast<JNIEnvExt*>(env_)->SetCheckJniEnabled(true); \
9721d99e4549309d05007d041d058b1878de88e9585Ian Rogers  } \
973814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Allocate an array and check it has the right type and length. */ \
974814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  scalar_type ## Array a = env_->new_fn(size); \
9752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(a, nullptr); \
976814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(a, env_->FindClass(expected_class_descriptor))); \
977814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(size, env_->GetArrayLength(a)); \
978d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
979d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  /* GetPrimitiveArrayRegion/SetPrimitiveArrayRegion */ \
980814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* AIOOBE for negative start offset. */ \
9812d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->get_region_fn(a, -1, 1, nullptr); \
9822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
9832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->set_region_fn(a, -1, 1, nullptr); \
9842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
985d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
986814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* AIOOBE for negative length. */ \
9872d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->get_region_fn(a, 0, -1, nullptr); \
9882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
9892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->set_region_fn(a, 0, -1, nullptr); \
9902d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
991d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
992814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* AIOOBE for buffer overrun. */ \
9932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->get_region_fn(a, size - 1, size, nullptr); \
9942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
9952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->set_region_fn(a, size - 1, size, nullptr); \
9962d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
997d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
9982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  /* It's okay for the buffer to be nullptr as long as the length is 0. */ \
9992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->get_region_fn(a, 2, 0, nullptr); \
1000d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  /* Even if the offset is invalid... */ \
10012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->get_region_fn(a, 123, 0, nullptr); \
10022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
1003d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
10042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  /* It's okay for the buffer to be nullptr as long as the length is 0. */ \
10052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->set_region_fn(a, 2, 0, nullptr); \
1006d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  /* Even if the offset is invalid... */ \
10072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->set_region_fn(a, 123, 0, nullptr); \
10082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
1009d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
1010814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Prepare a couple of buffers. */ \
1011700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<scalar_type[]> src_buf(new scalar_type[size]); \
1012700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<scalar_type[]> dst_buf(new scalar_type[size]); \
1013814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  for (jsize i = 0; i < size; ++i) { src_buf[i] = scalar_type(i); } \
1014814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  for (jsize i = 0; i < size; ++i) { dst_buf[i] = scalar_type(-1); } \
1015d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
1016814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Copy all of src_buf onto the heap. */ \
1017ee0fa76b2e5d39ad36d1ff144b2d0270df81e606Elliott Hughes  env_->set_region_fn(a, 0, size, &src_buf[0]); \
1018814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Copy back only part. */ \
1019814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  env_->get_region_fn(a, 1, size - 2, &dst_buf[1]); \
1020ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_NE(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1021ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    << "short copy equal"; \
1022814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Copy the missing pieces. */ \
1023ee0fa76b2e5d39ad36d1ff144b2d0270df81e606Elliott Hughes  env_->get_region_fn(a, 0, 1, &dst_buf[0]); \
1024814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  env_->get_region_fn(a, size - 1, 1, &dst_buf[size - 1]); \
1025ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1026ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    << "fixed copy not equal"; \
1027814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Copy back the whole array. */ \
1028ee0fa76b2e5d39ad36d1ff144b2d0270df81e606Elliott Hughes  env_->get_region_fn(a, 0, size, &dst_buf[0]); \
1029ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1030ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    << "full copy not equal"; \
10317577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  /* GetPrimitiveArrayCritical */ \
10322d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  void* v = env_->GetPrimitiveArrayCritical(a, nullptr); \
1033ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_EQ(memcmp(&src_buf[0], v, size * sizeof(scalar_type)), 0) \
1034ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    << "GetPrimitiveArrayCritical not equal"; \
10357577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleasePrimitiveArrayCritical(a, v, 0); \
10367577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  /* GetXArrayElements */ \
10372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  scalar_type* xs = env_->get_elements_fn(a, nullptr); \
1038ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_EQ(memcmp(&src_buf[0], xs, size * sizeof(scalar_type)), 0) \
1039ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    << # get_elements_fn " not equal"; \
10407577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->release_elements_fn(a, xs, 0); \
1041814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
1042814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, BooleanArrays) {
1043ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion,
1044ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetBooleanArrayElements, ReleaseBooleanArrayElements, jboolean, "[Z");
1045814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1046814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, ByteArrays) {
1047ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion,
1048ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetByteArrayElements, ReleaseByteArrayElements, jbyte, "[B");
1049814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1050814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, CharArrays) {
1051ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion,
1052ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetCharArrayElements, ReleaseCharArrayElements, jchar, "[C");
1053814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1054814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, DoubleArrays) {
1055ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion,
1056ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetDoubleArrayElements, ReleaseDoubleArrayElements, jdouble, "[D");
1057814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1058814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, FloatArrays) {
1059ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion,
1060ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetFloatArrayElements, ReleaseFloatArrayElements, jfloat, "[F");
1061814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1062814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, IntArrays) {
1063ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion,
1064ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetIntArrayElements, ReleaseIntArrayElements, jint, "[I");
1065814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1066814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, LongArrays) {
1067ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion,
1068ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetLongArrayElements, ReleaseLongArrayElements, jlong, "[J");
1069814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1070814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, ShortArrays) {
1071ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion,
1072ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetShortArrayElements, ReleaseShortArrayElements, jshort, "[S");
1073d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes}
1074d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes
10752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, GetPrimitiveArrayElementsOfWrongType) {
107668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetPrimitiveArrayElementsOfWrongType(false);
107768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetPrimitiveArrayElementsOfWrongType(true);
10782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers}
10792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
10802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, ReleasePrimitiveArrayElementsOfWrongType) {
108168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  ReleasePrimitiveArrayElementsOfWrongType(false);
108268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  ReleasePrimitiveArrayElementsOfWrongType(true);
10832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers}
108468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
10852d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, GetReleasePrimitiveArrayCriticalOfWrongType) {
108668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetReleasePrimitiveArrayCriticalOfWrongType(false);
108768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetReleasePrimitiveArrayCriticalOfWrongType(true);
10882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers}
10892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
10902d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, GetPrimitiveArrayRegionElementsOfWrongType) {
109168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetPrimitiveArrayRegionElementsOfWrongType(false);
109268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetPrimitiveArrayRegionElementsOfWrongType(true);
10932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers}
10942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
10952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, SetPrimitiveArrayRegionElementsOfWrongType) {
109668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  SetPrimitiveArrayRegionElementsOfWrongType(false);
109768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  SetPrimitiveArrayRegionElementsOfWrongType(true);
10982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers}
10992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
1100f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott HughesTEST_F(JniInternalTest, NewObjectArray) {
1101bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  jclass element_class = env_->FindClass("java/lang/String");
11022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(element_class, nullptr);
1103bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  jclass array_class = env_->FindClass("[Ljava/lang/String;");
11042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(array_class, nullptr);
1105f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
11061d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jobjectArray a = env_->NewObjectArray(0, element_class, nullptr);
11072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(a, nullptr);
1108bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1109bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  EXPECT_EQ(0, env_->GetArrayLength(a));
1110f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
11111d99e4549309d05007d041d058b1878de88e9585Ian Rogers  a = env_->NewObjectArray(1, element_class, nullptr);
11122d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(a, nullptr);
1113bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1114bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  EXPECT_EQ(1, env_->GetArrayLength(a));
11151d99e4549309d05007d041d058b1878de88e9585Ian Rogers  EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), nullptr));
11161d99e4549309d05007d041d058b1878de88e9585Ian Rogers
11172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Negative array length checks.
111868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  NewObjectArrayBadArguments(false);
111968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  NewObjectArrayBadArguments(true);
11201d99e4549309d05007d041d058b1878de88e9585Ian Rogers}
11211d99e4549309d05007d041d058b1878de88e9585Ian Rogers
11221d99e4549309d05007d041d058b1878de88e9585Ian RogersTEST_F(JniInternalTest, NewObjectArrayWithPrimitiveClasses) {
11231d99e4549309d05007d041d058b1878de88e9585Ian Rogers  const char* primitive_descriptors = "VZBSCIJFD";
11241d99e4549309d05007d041d058b1878de88e9585Ian Rogers  const char* primitive_names[] = {
11251d99e4549309d05007d041d058b1878de88e9585Ian Rogers      "void", "boolean", "byte", "short", "char", "int", "long", "float", "double"
11261d99e4549309d05007d041d058b1878de88e9585Ian Rogers  };
11271d99e4549309d05007d041d058b1878de88e9585Ian Rogers  ASSERT_EQ(strlen(primitive_descriptors), arraysize(primitive_names));
11281d99e4549309d05007d041d058b1878de88e9585Ian Rogers
112968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
11301d99e4549309d05007d041d058b1878de88e9585Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
11311d99e4549309d05007d041d058b1878de88e9585Ian Rogers  for (size_t i = 0; i < strlen(primitive_descriptors); ++i) {
11322d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->NewObjectArray(0, nullptr, nullptr);
11332d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("element_jclass == null");
11341d99e4549309d05007d041d058b1878de88e9585Ian Rogers    jclass primitive_class = GetPrimitiveClass(primitive_descriptors[i]);
11351d99e4549309d05007d041d058b1878de88e9585Ian Rogers    env_->NewObjectArray(1, primitive_class, nullptr);
11361d99e4549309d05007d041d058b1878de88e9585Ian Rogers    std::string error_msg(StringPrintf("not an object type: %s", primitive_names[i]));
11371d99e4549309d05007d041d058b1878de88e9585Ian Rogers    jni_abort_catcher.Check(error_msg.c_str());
11381d99e4549309d05007d041d058b1878de88e9585Ian Rogers  }
113968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
114068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  for (size_t i = 0; i < strlen(primitive_descriptors); ++i) {
114168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->NewObjectArray(0, nullptr, nullptr);
114268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("NewObjectArray received NULL jclass");
114368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass primitive_class = GetPrimitiveClass(primitive_descriptors[i]);
114468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->NewObjectArray(1, primitive_class, nullptr);
114568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    std::string error_msg(StringPrintf("not an object type: %s", primitive_names[i]));
114668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(error_msg.c_str());
114768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
114868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
11491d99e4549309d05007d041d058b1878de88e9585Ian Rogers}
11501d99e4549309d05007d041d058b1878de88e9585Ian Rogers
11511d99e4549309d05007d041d058b1878de88e9585Ian RogersTEST_F(JniInternalTest, NewObjectArrayWithInitialValue) {
11521d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jclass element_class = env_->FindClass("java/lang/String");
11532d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(element_class, nullptr);
11541d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jclass array_class = env_->FindClass("[Ljava/lang/String;");
11552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(array_class, nullptr);
11567577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
11577577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jstring s = env_->NewStringUTF("poop");
11581d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jobjectArray a = env_->NewObjectArray(2, element_class, s);
11592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(a, nullptr);
11607577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
11617577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(2, env_->GetArrayLength(a));
11627577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), s));
11637577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 1), s));
11641d99e4549309d05007d041d058b1878de88e9585Ian Rogers
11651d99e4549309d05007d041d058b1878de88e9585Ian Rogers  // Attempt to incorrect create an array of strings with initial value of string arrays.
11661d99e4549309d05007d041d058b1878de88e9585Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
11671d99e4549309d05007d041d058b1878de88e9585Ian Rogers  env_->NewObjectArray(2, element_class, a);
11681d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jni_abort_catcher.Check("cannot assign object of type 'java.lang.String[]' to array with element "
11691d99e4549309d05007d041d058b1878de88e9585Ian Rogers                          "type of 'java.lang.String'");
1170bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes}
1171f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
1172bd9359912e5398799f60649b86ae80644ec72627Elliott HughesTEST_F(JniInternalTest, GetArrayLength) {
11732f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  // Already tested in NewObjectArray/NewPrimitiveArray except for NULL.
11742f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  CheckJniAbortCatcher jni_abort_catcher;
11752f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
11762f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  EXPECT_EQ(0, env_->GetArrayLength(nullptr));
11772f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  jni_abort_catcher.Check("java_array == null");
11782f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
11792f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  EXPECT_EQ(JNI_ERR, env_->GetArrayLength(nullptr));
11802f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  jni_abort_catcher.Check("jarray was NULL");
11812f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
11828a26c5c4c74b09e2887593c733a22652a9f80d7cElliott Hughes}
11838a26c5c4c74b09e2887593c733a22652a9f80d7cElliott Hughes
118437f7a40f6789bb287f287a9af00777af9d6428eeElliott HughesTEST_F(JniInternalTest, GetObjectClass) {
118537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass string_class = env_->FindClass("java/lang/String");
11862d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(string_class, nullptr);
118737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass class_class = env_->FindClass("java/lang/Class");
11882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(class_class, nullptr);
118937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
119037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jstring s = env_->NewStringUTF("poop");
119137f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass c = env_->GetObjectClass(s);
119237f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  ASSERT_TRUE(env_->IsSameObject(string_class, c));
119337f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
119437f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass c2 = env_->GetObjectClass(c);
119537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2)));
11962d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
11972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Null as object should fail.
11982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
11992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetObjectClass(nullptr), nullptr);
12002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_object == null");
120137f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes}
120237f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
1203885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott HughesTEST_F(JniInternalTest, GetSuperclass) {
1204885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jclass object_class = env_->FindClass("java/lang/Object");
12052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(object_class, nullptr);
1206885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jclass string_class = env_->FindClass("java/lang/String");
12072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(string_class, nullptr);
1208dc18020e83aa1261d4f661f1f9330bda20dffd71Ian Rogers  jclass runnable_interface = env_->FindClass("java/lang/Runnable");
12092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(runnable_interface, nullptr);
1210885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class)));
12112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_EQ(env_->GetSuperclass(object_class), nullptr);
1212dc18020e83aa1261d4f661f1f9330bda20dffd71Ian Rogers  ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(runnable_interface)));
12132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
12142d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Null as class should fail.
12152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
121668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
12172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetSuperclass(nullptr), nullptr);
12182d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_class == null");
121968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
122068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(env_->GetSuperclass(nullptr), nullptr);
122168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("GetSuperclass received NULL jclass");
122268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1223885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes}
1224885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
122537f7a40f6789bb287f287a9af00777af9d6428eeElliott HughesTEST_F(JniInternalTest, IsAssignableFrom) {
122637f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass object_class = env_->FindClass("java/lang/Object");
12272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(object_class, nullptr);
122837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass string_class = env_->FindClass("java/lang/String");
12292d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(string_class, nullptr);
123037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
12311268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // A superclass is assignable from an instance of its
12321268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // subclass but not vice versa.
12331268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_TRUE(env_->IsAssignableFrom(string_class, object_class));
12341268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_FALSE(env_->IsAssignableFrom(object_class, string_class));
12351268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath
12361268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  jclass charsequence_interface = env_->FindClass("java/lang/CharSequence");
12371268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_NE(charsequence_interface, nullptr);
12381268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath
12391268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // An interface is assignable from an instance of an implementing
12401268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // class but not vice versa.
12411268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_TRUE(env_->IsAssignableFrom(string_class, charsequence_interface));
12421268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_FALSE(env_->IsAssignableFrom(charsequence_interface, string_class));
12431268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath
12441268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // Check that arrays are covariant.
12451268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  jclass string_array_class = env_->FindClass("[Ljava/lang/String;");
12461268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_NE(string_array_class, nullptr);
12471268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  jclass object_array_class = env_->FindClass("[Ljava/lang/Object;");
12481268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_NE(object_array_class, nullptr);
12491268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_TRUE(env_->IsAssignableFrom(string_array_class, object_array_class));
12501268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_FALSE(env_->IsAssignableFrom(object_array_class, string_array_class));
12511268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath
12521268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // Primitive types are tested in 004-JniTest.
12532d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
12542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Null as either class should fail.
12552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
125668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
12572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->IsAssignableFrom(nullptr, string_class), JNI_FALSE);
12582d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_class1 == null");
12592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->IsAssignableFrom(object_class, nullptr), JNI_FALSE);
12602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_class2 == null");
126168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
126268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(env_->IsAssignableFrom(nullptr, string_class), JNI_FALSE);
126368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("IsAssignableFrom received NULL jclass");
126468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(env_->IsAssignableFrom(object_class, nullptr), JNI_FALSE);
126568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("IsAssignableFrom received NULL jclass");
126668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
126737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes}
126837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
1269b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott HughesTEST_F(JniInternalTest, GetObjectRefType) {
1270b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jclass local = env_->FindClass("java/lang/Object");
12712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(local != nullptr);
1272b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(local));
1273b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1274b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jobject global = env_->NewGlobalRef(local);
1275b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ(JNIGlobalRefType, env_->GetObjectRefType(global));
1276b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1277b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jweak weak_global = env_->NewWeakGlobalRef(local);
1278b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ(JNIWeakGlobalRefType, env_->GetObjectRefType(weak_global));
1279b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1280c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
1281b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jobject invalid = reinterpret_cast<jobject>(this);
1282b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(invalid));
1283c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  jni_abort_catcher.Check("use of invalid jobject");
1284b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1285b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  // TODO: invoke a native method and test that its arguments are considered local references.
12862d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
12872d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Null as object should fail.
12882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(nullptr));
12892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_object == null");
1290b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes}
1291b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
12920859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu ChartierTEST_F(JniInternalTest, StaleWeakGlobal) {
12930859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  jclass java_lang_Class = env_->FindClass("java/lang/Class");
12942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(java_lang_Class, nullptr);
12952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jobjectArray local_ref = env_->NewObjectArray(1, java_lang_Class, nullptr);
12962d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(local_ref, nullptr);
12970859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  jweak weak_global = env_->NewWeakGlobalRef(local_ref);
12982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(weak_global, nullptr);
12990859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  env_->DeleteLocalRef(local_ref);
13000859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  Runtime::Current()->GetHeap()->CollectGarbage(false);  // GC should clear the weak global.
13010859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  jobject new_global_ref = env_->NewGlobalRef(weak_global);
13022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(new_global_ref, nullptr);
13030859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  jobject new_local_ref = env_->NewLocalRef(weak_global);
13042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(new_local_ref, nullptr);
13050859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier}
13060859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier
13078a26c5c4c74b09e2887593c733a22652a9f80d7cElliott HughesTEST_F(JniInternalTest, NewStringUTF) {
13082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->NewStringUTF(nullptr), nullptr);
1309814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  jstring s;
1310814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
1311814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  s = env_->NewStringUTF("");
13122d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(s, nullptr);
1313814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(0, env_->GetStringLength(s));
1314814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(0, env_->GetStringUTFLength(s));
1315814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  s = env_->NewStringUTF("hello");
13162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(s, nullptr);
1317814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(5, env_->GetStringLength(s));
1318814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(5, env_->GetStringUTFLength(s));
1319814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
1320814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  // TODO: check some non-ASCII strings.
1321814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1322814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
1323814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, NewString) {
1324814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  jchar chars[] = { 'h', 'i' };
1325814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  jstring s;
1326814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  s = env_->NewString(chars, 0);
13272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(s, nullptr);
1328814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(0, env_->GetStringLength(s));
1329814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(0, env_->GetStringUTFLength(s));
1330814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  s = env_->NewString(chars, 2);
13312d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(s, nullptr);
1332814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(2, env_->GetStringLength(s));
1333814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(2, env_->GetStringUTFLength(s));
1334814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
13358a26c5c4c74b09e2887593c733a22652a9f80d7cElliott Hughes  // TODO: check some non-ASCII strings.
1336f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes}
1337f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
133825e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse WilsonTEST_F(JniInternalTest, NewStringNullCharsZeroLength) {
13391d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jstring s = env_->NewString(nullptr, 0);
13402d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(s, nullptr);
134125e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse Wilson  EXPECT_EQ(0, env_->GetStringLength(s));
134225e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse Wilson}
134325e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse Wilson
13441d99e4549309d05007d041d058b1878de88e9585Ian RogersTEST_F(JniInternalTest, NewStringNullCharsNonzeroLength) {
13451d99e4549309d05007d041d058b1878de88e9585Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
13461d99e4549309d05007d041d058b1878de88e9585Ian Rogers  env_->NewString(nullptr, 1);
13471d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jni_abort_catcher.Check("chars == null && char_count > 0");
13481d99e4549309d05007d041d058b1878de88e9585Ian Rogers}
13491d99e4549309d05007d041d058b1878de88e9585Ian Rogers
13501d99e4549309d05007d041d058b1878de88e9585Ian RogersTEST_F(JniInternalTest, NewStringNegativeLength) {
13511d99e4549309d05007d041d058b1878de88e9585Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
135268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
13531d99e4549309d05007d041d058b1878de88e9585Ian Rogers  env_->NewString(nullptr, -1);
13541d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jni_abort_catcher.Check("char_count < 0: -1");
13551d99e4549309d05007d041d058b1878de88e9585Ian Rogers  env_->NewString(nullptr, std::numeric_limits<jint>::min());
13561d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jni_abort_catcher.Check("char_count < 0: -2147483648");
135768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
135868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  env_->NewString(nullptr, -1);
135968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("negative jsize: -1");
136068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  env_->NewString(nullptr, std::numeric_limits<jint>::min());
136168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("negative jsize: -2147483648");
136268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
136325e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse Wilson}
136425e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse Wilson
1365b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott HughesTEST_F(JniInternalTest, GetStringLength_GetStringUTFLength) {
1366b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  // Already tested in the NewString/NewStringUTF tests.
1367b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes}
1368b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1369b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott HughesTEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) {
1370b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jstring s = env_->NewStringUTF("hello");
13712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(s != nullptr);
1372b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
13732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, -1, 0, nullptr);
13742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
13752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, 0, -1, nullptr);
13762d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
13772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, 0, 10, nullptr);
13782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
13792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, 10, 1, nullptr);
13802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
1381b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1382b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jchar chars[4] = { 'x', 'x', 'x', 'x' };
1383b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  env_->GetStringRegion(s, 1, 2, &chars[1]);
1384b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('x', chars[0]);
1385b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('e', chars[1]);
1386b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('l', chars[2]);
1387b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('x', chars[3]);
1388b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
13892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // It's okay for the buffer to be nullptr as long as the length is 0.
13902d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, 2, 0, nullptr);
1391d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  // Even if the offset is invalid...
13922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, 123, 0, nullptr);
13932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
13942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
13952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, -1, 0, nullptr);
13962d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
13972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, 0, -1, nullptr);
13982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
13992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, 0, 10, nullptr);
14002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
14012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, 10, 1, nullptr);
14022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
1403b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1404b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  char bytes[4] = { 'x', 'x', 'x', 'x' };
1405b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  env_->GetStringUTFRegion(s, 1, 2, &bytes[1]);
1406b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('x', bytes[0]);
1407b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('e', bytes[1]);
1408b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('l', bytes[2]);
1409b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('x', bytes[3]);
1410d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes
14112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // It's okay for the buffer to be nullptr as long as the length is 0.
14122d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, 2, 0, nullptr);
1413d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  // Even if the offset is invalid...
14142d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, 123, 0, nullptr);
14152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
1416b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes}
1417b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
14187577075b147fd8fa37ca41e7a32d1124676776ceElliott HughesTEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) {
14192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Passing in a nullptr jstring is ignored normally, but caught by -Xcheck:jni.
142068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
1421b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  {
1422b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    CheckJniAbortCatcher check_jni_abort_catcher;
14232d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->GetStringUTFChars(nullptr, nullptr), nullptr);
142468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
142568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  {
142668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher check_jni_abort_catcher;
142768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
142868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetStringUTFChars(nullptr, nullptr), nullptr);
142968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check("GetStringUTFChars received NULL jstring");
143068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1431b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
14327577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
14337577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jstring s = env_->NewStringUTF("hello");
14342d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(s != nullptr);
14357577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
14362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  const char* utf = env_->GetStringUTFChars(s, nullptr);
14377577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_STREQ("hello", utf);
14387577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringUTFChars(s, utf);
14397577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
14407577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jboolean is_copy = JNI_FALSE;
14417577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  utf = env_->GetStringUTFChars(s, &is_copy);
14427577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(JNI_TRUE, is_copy);
14437577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_STREQ("hello", utf);
14447577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringUTFChars(s, utf);
14457577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes}
14467577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
14477577075b147fd8fa37ca41e7a32d1124676776ceElliott HughesTEST_F(JniInternalTest, GetStringChars_ReleaseStringChars) {
14487577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jstring s = env_->NewStringUTF("hello");
144956890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  ScopedObjectAccess soa(env_);
145056890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  mirror::String* s_m = soa.Decode<mirror::String*>(s);
14512d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(s != nullptr);
14527577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
14537577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
14542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  const jchar* chars = env_->GetStringChars(s, nullptr);
14557577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[0], chars[0]);
14567577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[1], chars[1]);
14577577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[2], chars[2]);
14587577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[3], chars[3]);
14597577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[4], chars[4]);
14607577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringChars(s, chars);
14617577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
14627577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jboolean is_copy = JNI_FALSE;
14637577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  chars = env_->GetStringChars(s, &is_copy);
146456890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  if (Runtime::Current()->GetHeap()->IsMovableObject(s_m->GetCharArray())) {
146556890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    EXPECT_EQ(JNI_TRUE, is_copy);
146656890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  } else {
146756890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    EXPECT_EQ(JNI_FALSE, is_copy);
146856890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  }
14697577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[0], chars[0]);
14707577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[1], chars[1]);
14717577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[2], chars[2]);
14727577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[3], chars[3]);
14737577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[4], chars[4]);
14747577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringChars(s, chars);
14757577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes}
14767577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
14777577075b147fd8fa37ca41e7a32d1124676776ceElliott HughesTEST_F(JniInternalTest, GetStringCritical_ReleaseStringCritical) {
14787577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jstring s = env_->NewStringUTF("hello");
14792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(s != nullptr);
14807577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
14817577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
14822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  const jchar* chars = env_->GetStringCritical(s, nullptr);
14837577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[0], chars[0]);
14847577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[1], chars[1]);
14857577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[2], chars[2]);
14867577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[3], chars[3]);
14877577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[4], chars[4]);
14887577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringCritical(s, chars);
14897577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
149056890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  jboolean is_copy = JNI_TRUE;
14917577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  chars = env_->GetStringCritical(s, &is_copy);
149256890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  EXPECT_EQ(JNI_FALSE, is_copy);
14937577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[0], chars[0]);
14947577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[1], chars[1]);
14957577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[2], chars[2]);
14967577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[3], chars[3]);
14977577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[4], chars[4]);
14987577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringCritical(s, chars);
14997577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes}
15007577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
1501814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) {
1502b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  jclass java_lang_Class = env_->FindClass("java/lang/Class");
15032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(java_lang_Class != nullptr);
1504289da82ae82438ab3aed1898c82fd87c16846e74Elliott Hughes
15052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jobjectArray array = env_->NewObjectArray(1, java_lang_Class, nullptr);
15062d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(array, nullptr);
15072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetObjectArrayElement(array, 0), nullptr);
1508b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  env_->SetObjectArrayElement(array, 0, java_lang_Class);
1509b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), java_lang_Class));
1510a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes
1511a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes  // ArrayIndexOutOfBounds for negative index.
1512b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  env_->SetObjectArrayElement(array, -1, java_lang_Class);
15132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_);
1514a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes
1515a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes  // ArrayIndexOutOfBounds for too-large index.
1516b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  env_->SetObjectArrayElement(array, 1, java_lang_Class);
15172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_);
1518a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes
1519b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  // ArrayStoreException thrown for bad types.
1520b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  env_->SetObjectArrayElement(array, 0, env_->NewStringUTF("not a jclass!"));
15212d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(ase_);
15222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
15232d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Null as array should fail.
15242d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
152568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
15262d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, env_->GetObjectArrayElement(nullptr, 0));
15272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_array == null");
15282d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->SetObjectArrayElement(nullptr, 0, nullptr);
15292d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_array == null");
153068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
153168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(nullptr, env_->GetObjectArrayElement(nullptr, 0));
153268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("jarray was NULL");
153368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  env_->SetObjectArrayElement(nullptr, 0, nullptr);
153468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("jarray was NULL");
153568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1536289da82ae82438ab3aed1898c82fd87c16846e74Elliott Hughes}
1537289da82ae82438ab3aed1898c82fd87c16846e74Elliott Hughes
1538647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers#define EXPECT_STATIC_PRIMITIVE_FIELD(expect_eq, type, field_name, sig, value1, value2) \
1539885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  do { \
1540885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \
15412d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_NE(fid, nullptr); \
1542885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    env_->SetStatic ## type ## Field(c, fid, value1); \
1543647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers    expect_eq(value1, env_->GetStatic ## type ## Field(c, fid)); \
1544885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    env_->SetStatic ## type ## Field(c, fid, value2); \
1545647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers    expect_eq(value2, env_->GetStatic ## type ## Field(c, fid)); \
15462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    \
154768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(false); \
154868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    { \
154968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      CheckJniAbortCatcher jni_abort_catcher; \
155068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      env_->GetStatic ## type ## Field(nullptr, fid); \
155168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      env_->SetStatic ## type ## Field(nullptr, fid, value1); \
155268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    } \
15532d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CheckJniAbortCatcher jni_abort_catcher; \
15542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->GetStatic ## type ## Field(c, nullptr); \
15552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("fid == null"); \
15562d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->SetStatic ## type ## Field(c, nullptr, value1); \
15572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("fid == null"); \
155868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    \
155968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); \
156068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetStatic ## type ## Field(nullptr, fid); \
156168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("received NULL jclass"); \
156268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetStatic ## type ## Field(nullptr, fid, value1); \
156368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("received NULL jclass"); \
156468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetStatic ## type ## Field(c, nullptr); \
156568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("jfieldID was NULL"); \
156668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetStatic ## type ## Field(c, nullptr, value1); \
156768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("jfieldID was NULL"); \
156868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); \
1569885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  } while (false)
1570885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1571647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers#define EXPECT_PRIMITIVE_FIELD(expect_eq, instance, type, field_name, sig, value1, value2) \
1572885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  do { \
1573885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    jfieldID fid = env_->GetFieldID(c, field_name, sig); \
15742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_NE(fid, nullptr); \
1575885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    env_->Set ## type ## Field(instance, fid, value1); \
1576647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers    expect_eq(value1, env_->Get ## type ## Field(instance, fid)); \
1577885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    env_->Set ## type ## Field(instance, fid, value2); \
1578647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers    expect_eq(value2, env_->Get ## type ## Field(instance, fid)); \
15792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    \
158068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(false); \
15812d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CheckJniAbortCatcher jni_abort_catcher; \
15822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->Get ## type ## Field(nullptr, fid); \
15832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("obj == null"); \
15842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->Set ## type ## Field(nullptr, fid, value1); \
15852d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("obj == null"); \
15862d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->Get ## type ## Field(instance, nullptr); \
15872d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("fid == null"); \
15882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->Set ## type ## Field(instance, nullptr, value1); \
15892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("fid == null"); \
159068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); \
159168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->Get ## type ## Field(nullptr, fid); \
159268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("field operation on NULL object:"); \
159368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->Set ## type ## Field(nullptr, fid, value1); \
159468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("field operation on NULL object:"); \
159568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->Get ## type ## Field(instance, nullptr); \
159668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("jfieldID was NULL"); \
159768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->Set ## type ## Field(instance, nullptr, value1); \
159868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("jfieldID was NULL"); \
159968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); \
1600885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  } while (false)
1601885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1602885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1603885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott HughesTEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) {
1604ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  TEST_DISABLED_FOR_PORTABLE();
160500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Thread::Current()->TransitionFromSuspendedToRunnable();
160600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  LoadDex("AllFields");
1607bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom  bool started = runtime_->Start();
16082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(started);
1609885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1610885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jclass c = env_->FindClass("AllFields");
16112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
1612885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jobject o = env_->AllocObject(c);
16132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
1614885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1615647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Boolean, "sZ", "Z", JNI_TRUE, JNI_FALSE);
1616647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Byte, "sB", "B", 1, 2);
1617647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Char, "sC", "C", 'a', 'b');
1618647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_DOUBLE_EQ, Double, "sD", "D", 1.0, 2.0);
1619647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_FLOAT_EQ, Float, "sF", "F", 1.0, 2.0);
1620647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Int, "sI", "I", 1, 2);
1621647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Long, "sJ", "J", 1, 2);
1622647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Short, "sS", "S", 1, 2);
1623647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers
1624647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Boolean, "iZ", "Z", JNI_TRUE, JNI_FALSE);
1625647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Byte, "iB", "B", 1, 2);
1626647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Char, "iC", "C", 'a', 'b');
1627647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_DOUBLE_EQ, o, Double, "iD", "D", 1.0, 2.0);
1628647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_FLOAT_EQ, o, Float, "iF", "F", 1.0, 2.0);
1629647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Int, "iI", "I", 1, 2);
1630647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Long, "iJ", "J", 1, 2);
1631647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Short, "iS", "S", 1, 2);
1632885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes}
1633885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1634885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott HughesTEST_F(JniInternalTest, GetObjectField_SetObjectField) {
1635ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  TEST_DISABLED_FOR_PORTABLE();
163600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Thread::Current()->TransitionFromSuspendedToRunnable();
163700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  LoadDex("AllFields");
163825c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom  runtime_->Start();
1639885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1640885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jclass c = env_->FindClass("AllFields");
16412d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
1642885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jobject o = env_->AllocObject(c);
16432d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
1644885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1645885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jstring s1 = env_->NewStringUTF("hello");
16462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s1, nullptr);
1647885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jstring s2 = env_->NewStringUTF("world");
16482d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s2, nullptr);
1649885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1650885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;");
16512d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s_fid, nullptr);
1652885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;");
16532d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(i_fid, nullptr);
1654885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1655885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  env_->SetStaticObjectField(c, s_fid, s1);
1656885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid)));
1657885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  env_->SetStaticObjectField(c, s_fid, s2);
1658885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid)));
1659885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1660885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  env_->SetObjectField(o, i_fid, s1);
1661885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid)));
1662885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  env_->SetObjectField(o, i_fid, s2);
1663885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid)));
1664885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes}
1665885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
16662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, NewLocalRef_nullptr) {
16672d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->NewLocalRef(nullptr), nullptr);
166818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
166918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
167018c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, NewLocalRef) {
167118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
16722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
167318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewLocalRef(s);
16742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, nullptr);
16752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, s);
167618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
16772ced6a534157d5d963693346904389c19775d2daElliott Hughes  EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(o));
167818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
167918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
16802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, DeleteLocalRef_nullptr) {
16812d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->DeleteLocalRef(nullptr);
168218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
168318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
168418c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, DeleteLocalRef) {
168518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
16862d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
168718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteLocalRef(s);
168818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
16893f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes  // Currently, deleting an already-deleted reference is just a CheckJNI warning.
1690b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  {
169168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(false);
169268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    {
169368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      CheckJniAbortCatcher check_jni_abort_catcher;
169468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      env_->DeleteLocalRef(s);
169568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    }
1696b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    CheckJniAbortCatcher check_jni_abort_catcher;
169768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
1698b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    env_->DeleteLocalRef(s);
1699c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    std::string expected(StringPrintf("use of deleted local reference %p", s));
1700a9137c6bbdf4a1883f7b3f836c269eeb2ff619b2Elliott Hughes    check_jni_abort_catcher.Check(expected.c_str());
170168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1702b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
170318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
170418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  s = env_->NewStringUTF("");
17052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
170618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewLocalRef(s);
17072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
170818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
170918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteLocalRef(s);
171018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteLocalRef(o);
171118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
171218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
1713aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott HughesTEST_F(JniInternalTest, PushLocalFrame_10395422) {
1714aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // The JNI specification is ambiguous about whether the given capacity is to be interpreted as a
1715aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // maximum or as a minimum, but it seems like it's supposed to be a minimum, and that's how
1716aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // Android historically treated it, and it's how the RI treats it. It's also the more useful
1717aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // interpretation!
1718aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  ASSERT_EQ(JNI_OK, env_->PushLocalFrame(0));
17192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->PopLocalFrame(nullptr);
1720aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes
1721aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // Negative capacities are not allowed.
1722aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(-1));
1723aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes
1724aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // And it's okay to have an upper limit. Ours is currently 512.
1725aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(8192));
1726aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes}
1727aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes
17282ced6a534157d5d963693346904389c19775d2daElliott HughesTEST_F(JniInternalTest, PushLocalFrame_PopLocalFrame) {
17292ced6a534157d5d963693346904389c19775d2daElliott Hughes  jobject original = env_->NewStringUTF("");
17302d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(original, nullptr);
17312ced6a534157d5d963693346904389c19775d2daElliott Hughes
17322ced6a534157d5d963693346904389c19775d2daElliott Hughes  jobject outer;
17332ced6a534157d5d963693346904389c19775d2daElliott Hughes  jobject inner1, inner2;
173400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(env_);
17352ced6a534157d5d963693346904389c19775d2daElliott Hughes  {
1736aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes    ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
17372ced6a534157d5d963693346904389c19775d2daElliott Hughes    outer = env_->NewLocalRef(original);
17382ced6a534157d5d963693346904389c19775d2daElliott Hughes
17392ced6a534157d5d963693346904389c19775d2daElliott Hughes    {
1740aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes      ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
17412ced6a534157d5d963693346904389c19775d2daElliott Hughes      inner1 = env_->NewLocalRef(outer);
17422ced6a534157d5d963693346904389c19775d2daElliott Hughes      inner2 = env_->NewStringUTF("survivor");
1743c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      EXPECT_NE(env_->PopLocalFrame(inner2), nullptr);
17442ced6a534157d5d963693346904389c19775d2daElliott Hughes    }
17452ced6a534157d5d963693346904389c19775d2daElliott Hughes
17462ced6a534157d5d963693346904389c19775d2daElliott Hughes    EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
17472ced6a534157d5d963693346904389c19775d2daElliott Hughes    EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(outer));
1748c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    {
1749c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      CheckJniAbortCatcher check_jni_abort_catcher;
1750c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
1751c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      check_jni_abort_catcher.Check("use of deleted local reference");
1752c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    }
17532ced6a534157d5d963693346904389c19775d2daElliott Hughes
17542ced6a534157d5d963693346904389c19775d2daElliott Hughes    // Our local reference for the survivor is invalid because the survivor
17552ced6a534157d5d963693346904389c19775d2daElliott Hughes    // gets a new local reference...
1756c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    {
1757c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      CheckJniAbortCatcher check_jni_abort_catcher;
1758c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
1759c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      check_jni_abort_catcher.Check("use of deleted local reference");
1760c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    }
17612ced6a534157d5d963693346904389c19775d2daElliott Hughes
1762c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    EXPECT_EQ(env_->PopLocalFrame(nullptr), nullptr);
17632ced6a534157d5d963693346904389c19775d2daElliott Hughes  }
17642ced6a534157d5d963693346904389c19775d2daElliott Hughes  EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
1765c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  CheckJniAbortCatcher check_jni_abort_catcher;
17662ced6a534157d5d963693346904389c19775d2daElliott Hughes  EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(outer));
1767c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  check_jni_abort_catcher.Check("use of deleted local reference");
17682ced6a534157d5d963693346904389c19775d2daElliott Hughes  EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
1769c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  check_jni_abort_catcher.Check("use of deleted local reference");
17702ced6a534157d5d963693346904389c19775d2daElliott Hughes  EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
1771c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  check_jni_abort_catcher.Check("use of deleted local reference");
17722ced6a534157d5d963693346904389c19775d2daElliott Hughes}
17732ced6a534157d5d963693346904389c19775d2daElliott Hughes
17742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, NewGlobalRef_nullptr) {
17752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->NewGlobalRef(nullptr), nullptr);
177618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
177718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
177818c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, NewGlobalRef) {
177918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
17802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
178118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewGlobalRef(s);
17822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, nullptr);
17832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, s);
178418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
17852d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetObjectRefType(o), JNIGlobalRefType);
178618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
178718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
17882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, DeleteGlobalRef_nullptr) {
17892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->DeleteGlobalRef(nullptr);
179018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
179118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
179218c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, DeleteGlobalRef) {
179318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
17942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
179518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
179618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewGlobalRef(s);
17972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
179818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteGlobalRef(o);
179918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
18003f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes  // Currently, deleting an already-deleted reference is just a CheckJNI warning.
1801b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  {
180268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(false);
180368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    {
180468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      CheckJniAbortCatcher check_jni_abort_catcher;
180568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      env_->DeleteGlobalRef(o);
180668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    }
1807b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    CheckJniAbortCatcher check_jni_abort_catcher;
180868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
1809b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    env_->DeleteGlobalRef(o);
1810c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    std::string expected(StringPrintf("use of deleted global reference %p", o));
1811a9137c6bbdf4a1883f7b3f836c269eeb2ff619b2Elliott Hughes    check_jni_abort_catcher.Check(expected.c_str());
181268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1813b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
181418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
181518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o1 = env_->NewGlobalRef(s);
18162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o1, nullptr);
181718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o2 = env_->NewGlobalRef(s);
18182d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o2, nullptr);
181918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
182018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteGlobalRef(o1);
182118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteGlobalRef(o2);
182218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
182318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
18242d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, NewWeakGlobalRef_nullptr) {
18252d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->NewWeakGlobalRef(nullptr),   nullptr);
182618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
182718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
182818c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, NewWeakGlobalRef) {
182918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
18302d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
183118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewWeakGlobalRef(s);
18322d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, nullptr);
18332d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, s);
183418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
18352d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetObjectRefType(o), JNIWeakGlobalRefType);
183618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
183718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
18382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, DeleteWeakGlobalRef_nullptr) {
18392d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->DeleteWeakGlobalRef(nullptr);
184018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
184118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
184218c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, DeleteWeakGlobalRef) {
184318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
18442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
184518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
184618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewWeakGlobalRef(s);
18472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
184818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteWeakGlobalRef(o);
184918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
18503f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes  // Currently, deleting an already-deleted reference is just a CheckJNI warning.
1851b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  {
185268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(false);
185368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    {
185468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      CheckJniAbortCatcher check_jni_abort_catcher;
185568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      env_->DeleteWeakGlobalRef(o);
185668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    }
1857b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    CheckJniAbortCatcher check_jni_abort_catcher;
185868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
1859b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    env_->DeleteWeakGlobalRef(o);
1860c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    std::string expected(StringPrintf("use of deleted weak global reference %p", o));
1861a9137c6bbdf4a1883f7b3f836c269eeb2ff619b2Elliott Hughes    check_jni_abort_catcher.Check(expected.c_str());
186268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1863b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
186418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
186518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o1 = env_->NewWeakGlobalRef(s);
18662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o1, nullptr);
186718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o2 = env_->NewWeakGlobalRef(s);
18682d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o2, nullptr);
186918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
187018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteWeakGlobalRef(o1);
187118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteWeakGlobalRef(o2);
187218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
187318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
18743a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei ZavjalovTEST_F(JniInternalTest, ExceptionDescribe) {
18753a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov  // This checks how ExceptionDescribe handles call without exception.
18763a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov  env_->ExceptionClear();
18773a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov  env_->ExceptionDescribe();
18783a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov}
18793a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov
188037f7a40f6789bb287f287a9af00777af9d6428eeElliott HughesTEST_F(JniInternalTest, Throw) {
188137f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass exception_class = env_->FindClass("java/lang/RuntimeException");
18822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(exception_class != nullptr);
188337f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class));
18842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(exception != nullptr);
188537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
188637f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  EXPECT_EQ(JNI_OK, env_->Throw(exception));
188737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  EXPECT_TRUE(env_->ExceptionCheck());
1888a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes  jthrowable thrown_exception = env_->ExceptionOccurred();
188937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  env_->ExceptionClear();
1890a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes  EXPECT_TRUE(env_->IsSameObject(exception, thrown_exception));
189137f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
189268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  // Bad argument.
189368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
18942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(JNI_ERR, env_->Throw(nullptr));
189568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
189668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  CheckJniAbortCatcher check_jni_abort_catcher;
189768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(JNI_ERR, env_->Throw(nullptr));
189868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  check_jni_abort_catcher.Check("Throw received NULL jthrowable");
189968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
190068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers}
190137f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
190268d8b42ddec39ec0174162d90d4abaa004d1983eIan RogersTEST_F(JniInternalTest, ThrowNew) {
190337f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass exception_class = env_->FindClass("java/lang/RuntimeException");
19042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(exception_class != nullptr);
190537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
19065cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  jthrowable thrown_exception;
19075cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes
190837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
190937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  EXPECT_TRUE(env_->ExceptionCheck());
19105cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  thrown_exception = env_->ExceptionOccurred();
19115cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  env_->ExceptionClear();
19125cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
19135cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes
19142d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, nullptr));
19155cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  EXPECT_TRUE(env_->ExceptionCheck());
19165cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  thrown_exception = env_->ExceptionOccurred();
191737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  env_->ExceptionClear();
1918a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
191968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
192068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  // Bad argument.
192168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
192268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  CheckJniAbortCatcher check_jni_abort_catcher;
192368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(JNI_ERR, env_->ThrowNew(nullptr, nullptr));
192468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  check_jni_abort_catcher.Check("c == null");
192568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
192668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(JNI_ERR, env_->ThrowNew(nullptr, nullptr));
192768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  check_jni_abort_catcher.Check("ThrowNew received NULL jclass");
192868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
192937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes}
193037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
19311d99e4549309d05007d041d058b1878de88e9585Ian RogersTEST_F(JniInternalTest, NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) {
19321d99e4549309d05007d041d058b1878de88e9585Ian Rogers  // Start runtime.
19331d99e4549309d05007d041d058b1878de88e9585Ian Rogers  Thread* self = Thread::Current();
19341d99e4549309d05007d041d058b1878de88e9585Ian Rogers  self->TransitionFromSuspendedToRunnable();
19351d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.lang.Class");
19361d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.lang.Object");
19371d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.DirectByteBuffer");
19381d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.MemoryBlock");
19391d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.MemoryBlock$UnmanagedBlock");
19401d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.MappedByteBuffer");
19411d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.ByteBuffer");
19421d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.Buffer");
19431d99e4549309d05007d041d058b1878de88e9585Ian Rogers  // TODO: we only load a dex file here as starting the runtime relies upon it.
19441d99e4549309d05007d041d058b1878de88e9585Ian Rogers  const char* class_name = "StaticLeafMethods";
19451d99e4549309d05007d041d058b1878de88e9585Ian Rogers  LoadDex(class_name);
19461d99e4549309d05007d041d058b1878de88e9585Ian Rogers  bool started = runtime_->Start();
19471d99e4549309d05007d041d058b1878de88e9585Ian Rogers  ASSERT_TRUE(started);
19481d99e4549309d05007d041d058b1878de88e9585Ian Rogers
1949b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jclass buffer_class = env_->FindClass("java/nio/Buffer");
19502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(buffer_class, nullptr);
1951b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1952b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  char bytes[1024];
1953b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes));
19542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(buffer, nullptr);
1955b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class));
19562d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_EQ(env_->GetDirectBufferAddress(buffer), bytes);
19571ee99352d85a07558688365dba70e9aa8f476c03Ian Rogers  ASSERT_EQ(env_->GetDirectBufferCapacity(buffer), static_cast<jlong>(sizeof(bytes)));
195845d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom
195945d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom  {
196045d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom    CheckJniAbortCatcher check_jni_abort_catcher;
196185a93364e5111dc56a73eed0130856e66cab0802Brian Carlstrom    env_->NewDirectByteBuffer(bytes, static_cast<jlong>(INT_MAX) + 1);
196245d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom    check_jni_abort_catcher.Check("in call to NewDirectByteBuffer");
196345d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom  }
1964b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes}
1965b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
19666d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian RogersTEST_F(JniInternalTest, MonitorEnterExit) {
19672d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Create an object to torture.
19686d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  jclass object_class = env_->FindClass("java/lang/Object");
19692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(object_class, nullptr);
19706d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  jobject object = env_->AllocObject(object_class);
19712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(object, nullptr);
19726d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
19736d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Expected class of exceptions
19746d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  jclass imse_class = env_->FindClass("java/lang/IllegalMonitorStateException");
19752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(imse_class, nullptr);
19766d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
19776d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  jthrowable thrown_exception;
19786d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
19796d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Unlock of unowned monitor
19806d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->MonitorExit(object);
19816d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_TRUE(env_->ExceptionCheck());
19826d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  thrown_exception = env_->ExceptionOccurred();
19836d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->ExceptionClear();
19846d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
19856d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
19866d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Lock of unowned monitor
19876d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->MonitorEnter(object);
19886d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
19896d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Regular unlock
19906d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->MonitorExit(object);
19916d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
19926d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
19936d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Recursively lock a lot
19946d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  size_t max_recursive_lock = 1024;
19956d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  for (size_t i = 0; i < max_recursive_lock; i++) {
19966d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    env_->MonitorEnter(object);
19976d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    EXPECT_FALSE(env_->ExceptionCheck());
19986d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  }
19996d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Recursively unlock a lot
20006d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  for (size_t i = 0; i < max_recursive_lock; i++) {
20016d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    env_->MonitorExit(object);
20026d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    EXPECT_FALSE(env_->ExceptionCheck());
20036d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  }
20046d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
20056d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Unlock of unowned monitor
20066d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->MonitorExit(object);
20076d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_TRUE(env_->ExceptionCheck());
20086d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  thrown_exception = env_->ExceptionOccurred();
20096d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->ExceptionClear();
20106d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
2011a92853eb60fbce1fa6d3bbd6a6013fb514fdf5cbElliott Hughes
20122d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // It's an error to call MonitorEnter or MonitorExit on nullptr.
2013b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  {
2014b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    CheckJniAbortCatcher check_jni_abort_catcher;
20152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->MonitorEnter(nullptr);
2016b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    check_jni_abort_catcher.Check("in call to MonitorEnter");
20172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->MonitorExit(nullptr);
2018b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    check_jni_abort_catcher.Check("in call to MonitorExit");
2019b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
20206d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers}
20216d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
20224d5714378c3433ba7e351cbf6a6713fb49c31784Brian CarlstromTEST_F(JniInternalTest, DetachCurrentThread) {
20234d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom  CleanUpJniEnv();  // cleanup now so TearDown won't have junk from wrong JNIEnv
20244d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom  jint ok = vm_->DetachCurrentThread();
20254d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom  EXPECT_EQ(JNI_OK, ok);
20264d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom
20274d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom  jint err = vm_->DetachCurrentThread();
20284d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom  EXPECT_EQ(JNI_ERR, err);
20292d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  vm_->AttachCurrentThread(&env_, nullptr);  // need attached thread for CommonRuntimeTest::TearDown
20304d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom}
20314d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom
20320cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers}  // namespace art
2033