jni_internal_test.cc revision 41da59665556e8dd5601178185c68d48d645500b
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);
80241da59665556e8dd5601178185c68d48d645500bMathieu Chartier  for (size_t i = 0; i <= 512; ++i) {
80341da59665556e8dd5601178185c68d48d645500bMathieu Chartier    // Regression test for b/18396311, ToReflectedField leaking local refs causing a local
80441da59665556e8dd5601178185c68d48d645500bMathieu Chartier    // reference table overflows with 512 references to ArtField
80541da59665556e8dd5601178185c68d48d645500bMathieu Chartier    env_->DeleteLocalRef(env_->ToReflectedField(c, fid, JNI_FALSE));
80641da59665556e8dd5601178185c68d48d645500bMathieu Chartier  }
8072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
808cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  ASSERT_TRUE(env_->IsInstanceOf(field, jlrField));
809cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // ...and back again.
810cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jfieldID fid2 = env_->FromReflectedField(field);
8112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(fid2, nullptr);
812ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  // Make sure we can actually use it.
813ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  jstring s = env_->NewStringUTF("poop");
814ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  ASSERT_EQ(4, env_->GetIntField(s, fid2));
8152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
8162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Bad arguments.
81768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetFromReflectedField_ToReflectedFieldBadArgumentTest(false);
81868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetFromReflectedField_ToReflectedFieldBadArgumentTest(true);
819cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes}
820cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
821cdf53120cd5a73cbedc1654e22542848468c0d2fElliott HughesTEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
822cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass jlrMethod = env_->FindClass("java/lang/reflect/Method");
823d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(jlrMethod, nullptr);
824d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  jclass jlrConstructor = env_->FindClass("java/lang/reflect/Constructor");
825d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(jlrConstructor, nullptr);
826cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass c = env_->FindClass("java/lang/String");
8272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
828d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz
829d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  jmethodID mid = env_->GetMethodID(c, "<init>", "()V");
8302d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(mid, nullptr);
831d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  // Turn the mid into a java.lang.reflect.Constructor...
832cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
83341da59665556e8dd5601178185c68d48d645500bMathieu Chartier  for (size_t i = 0; i <= 512; ++i) {
83441da59665556e8dd5601178185c68d48d645500bMathieu Chartier    // Regression test for b/18396311, ToReflectedMethod leaking local refs causing a local
83541da59665556e8dd5601178185c68d48d645500bMathieu Chartier    // reference table overflows with 512 references to ArtMethod
83641da59665556e8dd5601178185c68d48d645500bMathieu Chartier    env_->DeleteLocalRef(env_->ToReflectedMethod(c, mid, JNI_FALSE));
83741da59665556e8dd5601178185c68d48d645500bMathieu Chartier  }
838d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(method, nullptr);
839d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_TRUE(env_->IsInstanceOf(method, jlrConstructor));
840cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // ...and back again.
841cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jmethodID mid2 = env_->FromReflectedMethod(method);
8422d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(mid2, nullptr);
843ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  // Make sure we can actually use it.
844d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  jstring s = reinterpret_cast<jstring>(env_->AllocObject(c));
845d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(s, nullptr);
846d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  env_->CallVoidMethod(s, mid2);
847d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_EQ(JNI_FALSE, env_->ExceptionCheck());
848d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz
849d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  mid = env_->GetMethodID(c, "length", "()I");
850d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(mid, nullptr);
851d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  // Turn the mid into a java.lang.reflect.Method...
852d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
853d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(method, nullptr);
854d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod));
855d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  // ...and back again.
856d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  mid2 = env_->FromReflectedMethod(method);
857d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(mid2, nullptr);
858d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  // Make sure we can actually use it.
859d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  s = env_->NewStringUTF("poop");
860d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(s, nullptr);
8615d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers  ASSERT_EQ(4, env_->CallIntMethod(s, mid2));
8622d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
8632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Bad arguments.
86468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetFromReflectedMethod_ToReflectedMethodBadArgumentTest(false);
86568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetFromReflectedMethod_ToReflectedMethodBadArgumentTest(true);
866cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes}
867cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
8682d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogersstatic void BogusMethod() {
8692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // You can't pass nullptr function pointers to RegisterNatives.
8705174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes}
8715174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
8722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, RegisterAndUnregisterNatives) {
8734dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlobject = env_->FindClass("java/lang/Object");
8744dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
875fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  void* native_function = reinterpret_cast<void*>(BogusMethod);
8764dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
8772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Sanity check that no exceptions are pending.
878cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  ASSERT_FALSE(env_->ExceptionCheck());
8794dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
880fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  // Check that registering method without name causes a NoSuchMethodError.
881fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  {
882fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz    JNINativeMethod methods[] = { { nullptr, "()V", native_function } };
883fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz    EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
884fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  }
885fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  ExpectException(jlnsme);
886fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz
887fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  // Check that registering method without signature causes a NoSuchMethodError.
888fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  {
889fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz    JNINativeMethod methods[] = { { "notify", nullptr, native_function } };
890fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz    EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
891fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  }
892fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  ExpectException(jlnsme);
893fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz
894fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  // Check that registering method without function causes a NoSuchMethodError.
895fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  {
896fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz    JNINativeMethod methods[] = { { "notify", "()V", nullptr } };
897fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz    EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
898fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  }
899fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  ExpectException(jlnsme);
900fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz
9012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Check that registering to a non-existent java.lang.Object.foo() causes a NoSuchMethodError.
9024dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  {
903fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz    JNINativeMethod methods[] = { { "foo", "()V", native_function } };
9042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
9054dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  }
9062d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsme);
9074dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
9082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Check that registering non-native methods causes a NoSuchMethodError.
9094dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  {
910fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz    JNINativeMethod methods[] = { { "equals", "(Ljava/lang/Object;)Z", native_function } };
9112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
9124dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  }
9132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsme);
9144dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
9152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Check that registering native methods is successful.
9164dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  {
917fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz    JNINativeMethod methods[] = { { "notify", "()V", native_function } };
9182d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_OK);
9192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  }
9202d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
9212d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->UnregisterNatives(jlobject), JNI_OK);
9222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
9232d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Check that registering no methods isn't a failure.
9242d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  {
9252d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    JNINativeMethod methods[] = { };
9262d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 0), JNI_OK);
9272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  }
9282d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
9292d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->UnregisterNatives(jlobject), JNI_OK);
9302d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
9312d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Check that registering a -ve number of methods is a failure.
9322d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher check_jni_abort_catcher;
9332d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  for (int i = -10; i < 0; ++i) {
9342d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    JNINativeMethod methods[] = { };
9352d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->RegisterNatives(jlobject, methods, i), JNI_ERR);
9362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    check_jni_abort_catcher.Check("negative method count: ");
9374dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  }
9384dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
9395174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
9402d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Unregistering a class with no natives is a warning.
9412d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->UnregisterNatives(jlnsme), JNI_OK);
94268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
94368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  RegisterAndUnregisterNativesBadArguments(false, &check_jni_abort_catcher);
94468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  RegisterAndUnregisterNativesBadArguments(true, &check_jni_abort_catcher);
9454dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers}
9464dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
947ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#define EXPECT_PRIMITIVE_ARRAY(new_fn, \
948ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               get_region_fn, \
949ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               set_region_fn, \
950ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               get_elements_fn, \
951ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               release_elements_fn, \
952ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               scalar_type, \
953ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               expected_class_descriptor) \
9542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jsize size = 4; \
9552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  \
9561d99e4549309d05007d041d058b1878de88e9585Ian Rogers  { \
9571d99e4549309d05007d041d058b1878de88e9585Ian Rogers    CheckJniAbortCatcher jni_abort_catcher; \
95868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    down_cast<JNIEnvExt*>(env_)->SetCheckJniEnabled(false); \
9591d99e4549309d05007d041d058b1878de88e9585Ian Rogers    /* Allocate an negative sized array and check it has the right failure type. */ \
9602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->new_fn(-1), nullptr); \
9611d99e4549309d05007d041d058b1878de88e9585Ian Rogers    jni_abort_catcher.Check("negative array length: -1"); \
9622d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->new_fn(std::numeric_limits<jint>::min()), nullptr); \
9631d99e4549309d05007d041d058b1878de88e9585Ian Rogers    jni_abort_catcher.Check("negative array length: -2147483648"); \
9642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    /* Pass the array as null. */ \
9652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(0, env_->GetArrayLength(nullptr)); \
9662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("java_array == null"); \
9672d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->get_region_fn(nullptr, 0, 0, nullptr); \
9682d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("java_array == null"); \
9692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->set_region_fn(nullptr, 0, 0, nullptr); \
9702d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("java_array == null"); \
9712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->get_elements_fn(nullptr, nullptr); \
9722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("java_array == null"); \
9732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->release_elements_fn(nullptr, nullptr, 0); \
9742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("java_array == null"); \
9752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    /* Pass the elements for region as null. */ \
9762d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    scalar_type ## Array a = env_->new_fn(size); \
9772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->get_region_fn(a, 0, size, nullptr); \
9782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("buf == null"); \
9792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->set_region_fn(a, 0, size, nullptr); \
9802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("buf == null"); \
98168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    down_cast<JNIEnvExt*>(env_)->SetCheckJniEnabled(true); \
9821d99e4549309d05007d041d058b1878de88e9585Ian Rogers  } \
983814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Allocate an array and check it has the right type and length. */ \
984814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  scalar_type ## Array a = env_->new_fn(size); \
9852d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(a, nullptr); \
986814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(a, env_->FindClass(expected_class_descriptor))); \
987814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(size, env_->GetArrayLength(a)); \
988d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
989d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  /* GetPrimitiveArrayRegion/SetPrimitiveArrayRegion */ \
990814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* AIOOBE for negative start offset. */ \
9912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->get_region_fn(a, -1, 1, nullptr); \
9922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
9932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->set_region_fn(a, -1, 1, nullptr); \
9942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
995d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
996814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* AIOOBE for negative length. */ \
9972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->get_region_fn(a, 0, -1, nullptr); \
9982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
9992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->set_region_fn(a, 0, -1, nullptr); \
10002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
1001d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
1002814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* AIOOBE for buffer overrun. */ \
10032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->get_region_fn(a, size - 1, size, nullptr); \
10042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
10052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->set_region_fn(a, size - 1, size, nullptr); \
10062d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
1007d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
10082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  /* It's okay for the buffer to be nullptr as long as the length is 0. */ \
10092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->get_region_fn(a, 2, 0, nullptr); \
1010d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  /* Even if the offset is invalid... */ \
10112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->get_region_fn(a, 123, 0, nullptr); \
10122d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
1013d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
10142d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  /* It's okay for the buffer to be nullptr as long as the length is 0. */ \
10152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->set_region_fn(a, 2, 0, nullptr); \
1016d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  /* Even if the offset is invalid... */ \
10172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->set_region_fn(a, 123, 0, nullptr); \
10182d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
1019d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
1020814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Prepare a couple of buffers. */ \
1021700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<scalar_type[]> src_buf(new scalar_type[size]); \
1022700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<scalar_type[]> dst_buf(new scalar_type[size]); \
1023814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  for (jsize i = 0; i < size; ++i) { src_buf[i] = scalar_type(i); } \
1024814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  for (jsize i = 0; i < size; ++i) { dst_buf[i] = scalar_type(-1); } \
1025d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
1026814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Copy all of src_buf onto the heap. */ \
1027ee0fa76b2e5d39ad36d1ff144b2d0270df81e606Elliott Hughes  env_->set_region_fn(a, 0, size, &src_buf[0]); \
1028814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Copy back only part. */ \
1029814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  env_->get_region_fn(a, 1, size - 2, &dst_buf[1]); \
1030ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_NE(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1031ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    << "short copy equal"; \
1032814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Copy the missing pieces. */ \
1033ee0fa76b2e5d39ad36d1ff144b2d0270df81e606Elliott Hughes  env_->get_region_fn(a, 0, 1, &dst_buf[0]); \
1034814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  env_->get_region_fn(a, size - 1, 1, &dst_buf[size - 1]); \
1035ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1036ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    << "fixed copy not equal"; \
1037814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Copy back the whole array. */ \
1038ee0fa76b2e5d39ad36d1ff144b2d0270df81e606Elliott Hughes  env_->get_region_fn(a, 0, size, &dst_buf[0]); \
1039ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1040ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    << "full copy not equal"; \
10417577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  /* GetPrimitiveArrayCritical */ \
10422d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  void* v = env_->GetPrimitiveArrayCritical(a, nullptr); \
1043ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_EQ(memcmp(&src_buf[0], v, size * sizeof(scalar_type)), 0) \
1044ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    << "GetPrimitiveArrayCritical not equal"; \
10457577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleasePrimitiveArrayCritical(a, v, 0); \
10467577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  /* GetXArrayElements */ \
10472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  scalar_type* xs = env_->get_elements_fn(a, nullptr); \
1048ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_EQ(memcmp(&src_buf[0], xs, size * sizeof(scalar_type)), 0) \
1049ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    << # get_elements_fn " not equal"; \
10507577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->release_elements_fn(a, xs, 0); \
1051814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
1052814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, BooleanArrays) {
1053ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion,
1054ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetBooleanArrayElements, ReleaseBooleanArrayElements, jboolean, "[Z");
1055814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1056814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, ByteArrays) {
1057ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion,
1058ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetByteArrayElements, ReleaseByteArrayElements, jbyte, "[B");
1059814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1060814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, CharArrays) {
1061ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion,
1062ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetCharArrayElements, ReleaseCharArrayElements, jchar, "[C");
1063814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1064814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, DoubleArrays) {
1065ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion,
1066ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetDoubleArrayElements, ReleaseDoubleArrayElements, jdouble, "[D");
1067814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1068814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, FloatArrays) {
1069ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion,
1070ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetFloatArrayElements, ReleaseFloatArrayElements, jfloat, "[F");
1071814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1072814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, IntArrays) {
1073ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion,
1074ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetIntArrayElements, ReleaseIntArrayElements, jint, "[I");
1075814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1076814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, LongArrays) {
1077ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion,
1078ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetLongArrayElements, ReleaseLongArrayElements, jlong, "[J");
1079814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1080814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, ShortArrays) {
1081ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion,
1082ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetShortArrayElements, ReleaseShortArrayElements, jshort, "[S");
1083d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes}
1084d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes
10852d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, GetPrimitiveArrayElementsOfWrongType) {
108668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetPrimitiveArrayElementsOfWrongType(false);
108768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetPrimitiveArrayElementsOfWrongType(true);
10882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers}
10892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
10902d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, ReleasePrimitiveArrayElementsOfWrongType) {
109168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  ReleasePrimitiveArrayElementsOfWrongType(false);
109268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  ReleasePrimitiveArrayElementsOfWrongType(true);
10932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers}
109468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
10952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, GetReleasePrimitiveArrayCriticalOfWrongType) {
109668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetReleasePrimitiveArrayCriticalOfWrongType(false);
109768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetReleasePrimitiveArrayCriticalOfWrongType(true);
10982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers}
10992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
11002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, GetPrimitiveArrayRegionElementsOfWrongType) {
110168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetPrimitiveArrayRegionElementsOfWrongType(false);
110268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetPrimitiveArrayRegionElementsOfWrongType(true);
11032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers}
11042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
11052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, SetPrimitiveArrayRegionElementsOfWrongType) {
110668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  SetPrimitiveArrayRegionElementsOfWrongType(false);
110768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  SetPrimitiveArrayRegionElementsOfWrongType(true);
11082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers}
11092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
1110f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott HughesTEST_F(JniInternalTest, NewObjectArray) {
1111bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  jclass element_class = env_->FindClass("java/lang/String");
11122d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(element_class, nullptr);
1113bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  jclass array_class = env_->FindClass("[Ljava/lang/String;");
11142d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(array_class, nullptr);
1115f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
11161d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jobjectArray a = env_->NewObjectArray(0, element_class, nullptr);
11172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(a, nullptr);
1118bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1119bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  EXPECT_EQ(0, env_->GetArrayLength(a));
1120f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
11211d99e4549309d05007d041d058b1878de88e9585Ian Rogers  a = env_->NewObjectArray(1, element_class, nullptr);
11222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(a, nullptr);
1123bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1124bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  EXPECT_EQ(1, env_->GetArrayLength(a));
11251d99e4549309d05007d041d058b1878de88e9585Ian Rogers  EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), nullptr));
11261d99e4549309d05007d041d058b1878de88e9585Ian Rogers
11272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Negative array length checks.
112868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  NewObjectArrayBadArguments(false);
112968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  NewObjectArrayBadArguments(true);
11301d99e4549309d05007d041d058b1878de88e9585Ian Rogers}
11311d99e4549309d05007d041d058b1878de88e9585Ian Rogers
11321d99e4549309d05007d041d058b1878de88e9585Ian RogersTEST_F(JniInternalTest, NewObjectArrayWithPrimitiveClasses) {
11331d99e4549309d05007d041d058b1878de88e9585Ian Rogers  const char* primitive_descriptors = "VZBSCIJFD";
11341d99e4549309d05007d041d058b1878de88e9585Ian Rogers  const char* primitive_names[] = {
11351d99e4549309d05007d041d058b1878de88e9585Ian Rogers      "void", "boolean", "byte", "short", "char", "int", "long", "float", "double"
11361d99e4549309d05007d041d058b1878de88e9585Ian Rogers  };
11371d99e4549309d05007d041d058b1878de88e9585Ian Rogers  ASSERT_EQ(strlen(primitive_descriptors), arraysize(primitive_names));
11381d99e4549309d05007d041d058b1878de88e9585Ian Rogers
113968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
11401d99e4549309d05007d041d058b1878de88e9585Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
11411d99e4549309d05007d041d058b1878de88e9585Ian Rogers  for (size_t i = 0; i < strlen(primitive_descriptors); ++i) {
11422d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->NewObjectArray(0, nullptr, nullptr);
11432d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("element_jclass == null");
11441d99e4549309d05007d041d058b1878de88e9585Ian Rogers    jclass primitive_class = GetPrimitiveClass(primitive_descriptors[i]);
11451d99e4549309d05007d041d058b1878de88e9585Ian Rogers    env_->NewObjectArray(1, primitive_class, nullptr);
11461d99e4549309d05007d041d058b1878de88e9585Ian Rogers    std::string error_msg(StringPrintf("not an object type: %s", primitive_names[i]));
11471d99e4549309d05007d041d058b1878de88e9585Ian Rogers    jni_abort_catcher.Check(error_msg.c_str());
11481d99e4549309d05007d041d058b1878de88e9585Ian Rogers  }
114968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
115068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  for (size_t i = 0; i < strlen(primitive_descriptors); ++i) {
115168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->NewObjectArray(0, nullptr, nullptr);
115268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("NewObjectArray received NULL jclass");
115368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass primitive_class = GetPrimitiveClass(primitive_descriptors[i]);
115468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->NewObjectArray(1, primitive_class, nullptr);
115568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    std::string error_msg(StringPrintf("not an object type: %s", primitive_names[i]));
115668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(error_msg.c_str());
115768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
115868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
11591d99e4549309d05007d041d058b1878de88e9585Ian Rogers}
11601d99e4549309d05007d041d058b1878de88e9585Ian Rogers
11611d99e4549309d05007d041d058b1878de88e9585Ian RogersTEST_F(JniInternalTest, NewObjectArrayWithInitialValue) {
11621d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jclass element_class = env_->FindClass("java/lang/String");
11632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(element_class, nullptr);
11641d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jclass array_class = env_->FindClass("[Ljava/lang/String;");
11652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(array_class, nullptr);
11667577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
11677577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jstring s = env_->NewStringUTF("poop");
11681d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jobjectArray a = env_->NewObjectArray(2, element_class, s);
11692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(a, nullptr);
11707577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
11717577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(2, env_->GetArrayLength(a));
11727577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), s));
11737577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 1), s));
11741d99e4549309d05007d041d058b1878de88e9585Ian Rogers
11751d99e4549309d05007d041d058b1878de88e9585Ian Rogers  // Attempt to incorrect create an array of strings with initial value of string arrays.
11761d99e4549309d05007d041d058b1878de88e9585Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
11771d99e4549309d05007d041d058b1878de88e9585Ian Rogers  env_->NewObjectArray(2, element_class, a);
11781d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jni_abort_catcher.Check("cannot assign object of type 'java.lang.String[]' to array with element "
11791d99e4549309d05007d041d058b1878de88e9585Ian Rogers                          "type of 'java.lang.String'");
1180bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes}
1181f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
1182bd9359912e5398799f60649b86ae80644ec72627Elliott HughesTEST_F(JniInternalTest, GetArrayLength) {
11832f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  // Already tested in NewObjectArray/NewPrimitiveArray except for NULL.
11842f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  CheckJniAbortCatcher jni_abort_catcher;
11852f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
11862f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  EXPECT_EQ(0, env_->GetArrayLength(nullptr));
11872f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  jni_abort_catcher.Check("java_array == null");
11882f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
11892f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  EXPECT_EQ(JNI_ERR, env_->GetArrayLength(nullptr));
11902f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  jni_abort_catcher.Check("jarray was NULL");
11912f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
11928a26c5c4c74b09e2887593c733a22652a9f80d7cElliott Hughes}
11938a26c5c4c74b09e2887593c733a22652a9f80d7cElliott Hughes
119437f7a40f6789bb287f287a9af00777af9d6428eeElliott HughesTEST_F(JniInternalTest, GetObjectClass) {
119537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass string_class = env_->FindClass("java/lang/String");
11962d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(string_class, nullptr);
119737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass class_class = env_->FindClass("java/lang/Class");
11982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(class_class, nullptr);
119937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
120037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jstring s = env_->NewStringUTF("poop");
120137f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass c = env_->GetObjectClass(s);
120237f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  ASSERT_TRUE(env_->IsSameObject(string_class, c));
120337f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
120437f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass c2 = env_->GetObjectClass(c);
120537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2)));
12062d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
12072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Null as object should fail.
12082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
12092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetObjectClass(nullptr), nullptr);
12102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_object == null");
121137f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes}
121237f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
1213885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott HughesTEST_F(JniInternalTest, GetSuperclass) {
1214885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jclass object_class = env_->FindClass("java/lang/Object");
12152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(object_class, nullptr);
1216885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jclass string_class = env_->FindClass("java/lang/String");
12172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(string_class, nullptr);
1218dc18020e83aa1261d4f661f1f9330bda20dffd71Ian Rogers  jclass runnable_interface = env_->FindClass("java/lang/Runnable");
12192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(runnable_interface, nullptr);
1220885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class)));
12212d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_EQ(env_->GetSuperclass(object_class), nullptr);
1222dc18020e83aa1261d4f661f1f9330bda20dffd71Ian Rogers  ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(runnable_interface)));
12232d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
12242d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Null as class should fail.
12252d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
122668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
12272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetSuperclass(nullptr), nullptr);
12282d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_class == null");
122968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
123068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(env_->GetSuperclass(nullptr), nullptr);
123168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("GetSuperclass received NULL jclass");
123268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1233885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes}
1234885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
123537f7a40f6789bb287f287a9af00777af9d6428eeElliott HughesTEST_F(JniInternalTest, IsAssignableFrom) {
123637f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass object_class = env_->FindClass("java/lang/Object");
12372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(object_class, nullptr);
123837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass string_class = env_->FindClass("java/lang/String");
12392d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(string_class, nullptr);
124037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
12411268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // A superclass is assignable from an instance of its
12421268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // subclass but not vice versa.
12431268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_TRUE(env_->IsAssignableFrom(string_class, object_class));
12441268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_FALSE(env_->IsAssignableFrom(object_class, string_class));
12451268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath
12461268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  jclass charsequence_interface = env_->FindClass("java/lang/CharSequence");
12471268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_NE(charsequence_interface, nullptr);
12481268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath
12491268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // An interface is assignable from an instance of an implementing
12501268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // class but not vice versa.
12511268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_TRUE(env_->IsAssignableFrom(string_class, charsequence_interface));
12521268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_FALSE(env_->IsAssignableFrom(charsequence_interface, string_class));
12531268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath
12541268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // Check that arrays are covariant.
12551268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  jclass string_array_class = env_->FindClass("[Ljava/lang/String;");
12561268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_NE(string_array_class, nullptr);
12571268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  jclass object_array_class = env_->FindClass("[Ljava/lang/Object;");
12581268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_NE(object_array_class, nullptr);
12591268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_TRUE(env_->IsAssignableFrom(string_array_class, object_array_class));
12601268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_FALSE(env_->IsAssignableFrom(object_array_class, string_array_class));
12611268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath
12621268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // Primitive types are tested in 004-JniTest.
12632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
12642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Null as either class should fail.
12652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
126668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
12672d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->IsAssignableFrom(nullptr, string_class), JNI_FALSE);
12682d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_class1 == null");
12692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->IsAssignableFrom(object_class, nullptr), JNI_FALSE);
12702d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_class2 == null");
127168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
127268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(env_->IsAssignableFrom(nullptr, string_class), JNI_FALSE);
127368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("IsAssignableFrom received NULL jclass");
127468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(env_->IsAssignableFrom(object_class, nullptr), JNI_FALSE);
127568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("IsAssignableFrom received NULL jclass");
127668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
127737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes}
127837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
1279b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott HughesTEST_F(JniInternalTest, GetObjectRefType) {
1280b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jclass local = env_->FindClass("java/lang/Object");
12812d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(local != nullptr);
1282b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(local));
1283b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1284b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jobject global = env_->NewGlobalRef(local);
1285b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ(JNIGlobalRefType, env_->GetObjectRefType(global));
1286b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1287b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jweak weak_global = env_->NewWeakGlobalRef(local);
1288b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ(JNIWeakGlobalRefType, env_->GetObjectRefType(weak_global));
1289b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1290c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
1291b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jobject invalid = reinterpret_cast<jobject>(this);
1292b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(invalid));
1293c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  jni_abort_catcher.Check("use of invalid jobject");
1294b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1295b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  // TODO: invoke a native method and test that its arguments are considered local references.
12962d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
12972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Null as object should fail.
12982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(nullptr));
12992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_object == null");
1300b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes}
1301b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
13020859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu ChartierTEST_F(JniInternalTest, StaleWeakGlobal) {
13030859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  jclass java_lang_Class = env_->FindClass("java/lang/Class");
13042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(java_lang_Class, nullptr);
13052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jobjectArray local_ref = env_->NewObjectArray(1, java_lang_Class, nullptr);
13062d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(local_ref, nullptr);
13070859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  jweak weak_global = env_->NewWeakGlobalRef(local_ref);
13082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(weak_global, nullptr);
13090859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  env_->DeleteLocalRef(local_ref);
13100859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  Runtime::Current()->GetHeap()->CollectGarbage(false);  // GC should clear the weak global.
13110859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  jobject new_global_ref = env_->NewGlobalRef(weak_global);
13122d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(new_global_ref, nullptr);
13130859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  jobject new_local_ref = env_->NewLocalRef(weak_global);
13142d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(new_local_ref, nullptr);
13150859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier}
13160859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier
13178a26c5c4c74b09e2887593c733a22652a9f80d7cElliott HughesTEST_F(JniInternalTest, NewStringUTF) {
13182d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->NewStringUTF(nullptr), nullptr);
1319814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  jstring s;
1320814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
1321814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  s = env_->NewStringUTF("");
13222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(s, nullptr);
1323814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(0, env_->GetStringLength(s));
1324814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(0, env_->GetStringUTFLength(s));
1325814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  s = env_->NewStringUTF("hello");
13262d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(s, nullptr);
1327814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(5, env_->GetStringLength(s));
1328814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(5, env_->GetStringUTFLength(s));
1329814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
1330814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  // TODO: check some non-ASCII strings.
1331814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1332814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
1333814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, NewString) {
1334814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  jchar chars[] = { 'h', 'i' };
1335814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  jstring s;
1336814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  s = env_->NewString(chars, 0);
13372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(s, nullptr);
1338814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(0, env_->GetStringLength(s));
1339814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(0, env_->GetStringUTFLength(s));
1340814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  s = env_->NewString(chars, 2);
13412d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(s, nullptr);
1342814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(2, env_->GetStringLength(s));
1343814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(2, env_->GetStringUTFLength(s));
1344814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
13458a26c5c4c74b09e2887593c733a22652a9f80d7cElliott Hughes  // TODO: check some non-ASCII strings.
1346f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes}
1347f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
134825e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse WilsonTEST_F(JniInternalTest, NewStringNullCharsZeroLength) {
13491d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jstring s = env_->NewString(nullptr, 0);
13502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(s, nullptr);
135125e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse Wilson  EXPECT_EQ(0, env_->GetStringLength(s));
135225e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse Wilson}
135325e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse Wilson
13541d99e4549309d05007d041d058b1878de88e9585Ian RogersTEST_F(JniInternalTest, NewStringNullCharsNonzeroLength) {
13551d99e4549309d05007d041d058b1878de88e9585Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
13561d99e4549309d05007d041d058b1878de88e9585Ian Rogers  env_->NewString(nullptr, 1);
13571d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jni_abort_catcher.Check("chars == null && char_count > 0");
13581d99e4549309d05007d041d058b1878de88e9585Ian Rogers}
13591d99e4549309d05007d041d058b1878de88e9585Ian Rogers
13601d99e4549309d05007d041d058b1878de88e9585Ian RogersTEST_F(JniInternalTest, NewStringNegativeLength) {
13611d99e4549309d05007d041d058b1878de88e9585Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
136268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
13631d99e4549309d05007d041d058b1878de88e9585Ian Rogers  env_->NewString(nullptr, -1);
13641d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jni_abort_catcher.Check("char_count < 0: -1");
13651d99e4549309d05007d041d058b1878de88e9585Ian Rogers  env_->NewString(nullptr, std::numeric_limits<jint>::min());
13661d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jni_abort_catcher.Check("char_count < 0: -2147483648");
136768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
136868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  env_->NewString(nullptr, -1);
136968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("negative jsize: -1");
137068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  env_->NewString(nullptr, std::numeric_limits<jint>::min());
137168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("negative jsize: -2147483648");
137268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
137325e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse Wilson}
137425e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse Wilson
1375b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott HughesTEST_F(JniInternalTest, GetStringLength_GetStringUTFLength) {
1376b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  // Already tested in the NewString/NewStringUTF tests.
1377b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes}
1378b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1379b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott HughesTEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) {
1380b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jstring s = env_->NewStringUTF("hello");
13812d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(s != nullptr);
1382b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
13832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, -1, 0, nullptr);
13842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
13852d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, 0, -1, nullptr);
13862d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
13872d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, 0, 10, nullptr);
13882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
13892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, 10, 1, nullptr);
13902d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
1391b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1392b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jchar chars[4] = { 'x', 'x', 'x', 'x' };
1393b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  env_->GetStringRegion(s, 1, 2, &chars[1]);
1394b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('x', chars[0]);
1395b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('e', chars[1]);
1396b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('l', chars[2]);
1397b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('x', chars[3]);
1398b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
13992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // It's okay for the buffer to be nullptr as long as the length is 0.
14002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, 2, 0, nullptr);
1401d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  // Even if the offset is invalid...
14022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, 123, 0, nullptr);
14032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
14042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
14052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, -1, 0, nullptr);
14062d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
14072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, 0, -1, nullptr);
14082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
14092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, 0, 10, nullptr);
14102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
14112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, 10, 1, nullptr);
14122d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
1413b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1414b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  char bytes[4] = { 'x', 'x', 'x', 'x' };
1415b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  env_->GetStringUTFRegion(s, 1, 2, &bytes[1]);
1416b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('x', bytes[0]);
1417b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('e', bytes[1]);
1418b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('l', bytes[2]);
1419b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('x', bytes[3]);
1420d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes
14212d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // It's okay for the buffer to be nullptr as long as the length is 0.
14222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, 2, 0, nullptr);
1423d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  // Even if the offset is invalid...
14242d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, 123, 0, nullptr);
14252d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
1426b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes}
1427b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
14287577075b147fd8fa37ca41e7a32d1124676776ceElliott HughesTEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) {
14292d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Passing in a nullptr jstring is ignored normally, but caught by -Xcheck:jni.
143068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
1431b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  {
1432b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    CheckJniAbortCatcher check_jni_abort_catcher;
14332d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->GetStringUTFChars(nullptr, nullptr), nullptr);
143468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
143568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  {
143668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher check_jni_abort_catcher;
143768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
143868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetStringUTFChars(nullptr, nullptr), nullptr);
143968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check("GetStringUTFChars received NULL jstring");
144068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1441b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
14427577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
14437577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jstring s = env_->NewStringUTF("hello");
14442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(s != nullptr);
14457577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
14462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  const char* utf = env_->GetStringUTFChars(s, nullptr);
14477577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_STREQ("hello", utf);
14487577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringUTFChars(s, utf);
14497577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
14507577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jboolean is_copy = JNI_FALSE;
14517577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  utf = env_->GetStringUTFChars(s, &is_copy);
14527577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(JNI_TRUE, is_copy);
14537577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_STREQ("hello", utf);
14547577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringUTFChars(s, utf);
14557577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes}
14567577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
14577577075b147fd8fa37ca41e7a32d1124676776ceElliott HughesTEST_F(JniInternalTest, GetStringChars_ReleaseStringChars) {
14587577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jstring s = env_->NewStringUTF("hello");
145956890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  ScopedObjectAccess soa(env_);
146056890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  mirror::String* s_m = soa.Decode<mirror::String*>(s);
14612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(s != nullptr);
14627577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
14637577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
14642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  const jchar* chars = env_->GetStringChars(s, nullptr);
14657577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[0], chars[0]);
14667577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[1], chars[1]);
14677577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[2], chars[2]);
14687577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[3], chars[3]);
14697577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[4], chars[4]);
14707577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringChars(s, chars);
14717577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
14727577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jboolean is_copy = JNI_FALSE;
14737577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  chars = env_->GetStringChars(s, &is_copy);
147456890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  if (Runtime::Current()->GetHeap()->IsMovableObject(s_m->GetCharArray())) {
147556890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    EXPECT_EQ(JNI_TRUE, is_copy);
147656890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  } else {
147756890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    EXPECT_EQ(JNI_FALSE, is_copy);
147856890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  }
14797577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[0], chars[0]);
14807577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[1], chars[1]);
14817577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[2], chars[2]);
14827577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[3], chars[3]);
14837577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[4], chars[4]);
14847577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringChars(s, chars);
14857577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes}
14867577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
14877577075b147fd8fa37ca41e7a32d1124676776ceElliott HughesTEST_F(JniInternalTest, GetStringCritical_ReleaseStringCritical) {
14887577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jstring s = env_->NewStringUTF("hello");
14892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(s != nullptr);
14907577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
14917577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
14922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  const jchar* chars = env_->GetStringCritical(s, nullptr);
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
150056890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  jboolean is_copy = JNI_TRUE;
15017577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  chars = env_->GetStringCritical(s, &is_copy);
150256890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  EXPECT_EQ(JNI_FALSE, is_copy);
15037577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[0], chars[0]);
15047577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[1], chars[1]);
15057577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[2], chars[2]);
15067577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[3], chars[3]);
15077577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[4], chars[4]);
15087577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringCritical(s, chars);
15097577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes}
15107577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
1511814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) {
1512b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  jclass java_lang_Class = env_->FindClass("java/lang/Class");
15132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(java_lang_Class != nullptr);
1514289da82ae82438ab3aed1898c82fd87c16846e74Elliott Hughes
15152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jobjectArray array = env_->NewObjectArray(1, java_lang_Class, nullptr);
15162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(array, nullptr);
15172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetObjectArrayElement(array, 0), nullptr);
1518b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  env_->SetObjectArrayElement(array, 0, java_lang_Class);
1519b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), java_lang_Class));
1520a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes
1521a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes  // ArrayIndexOutOfBounds for negative index.
1522b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  env_->SetObjectArrayElement(array, -1, java_lang_Class);
15232d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_);
1524a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes
1525a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes  // ArrayIndexOutOfBounds for too-large index.
1526b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  env_->SetObjectArrayElement(array, 1, java_lang_Class);
15272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_);
1528a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes
1529b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  // ArrayStoreException thrown for bad types.
1530b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  env_->SetObjectArrayElement(array, 0, env_->NewStringUTF("not a jclass!"));
15312d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(ase_);
15322d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
15332d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Null as array should fail.
15342d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
153568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
15362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, env_->GetObjectArrayElement(nullptr, 0));
15372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_array == null");
15382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->SetObjectArrayElement(nullptr, 0, nullptr);
15392d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_array == null");
154068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
154168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(nullptr, env_->GetObjectArrayElement(nullptr, 0));
154268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("jarray was NULL");
154368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  env_->SetObjectArrayElement(nullptr, 0, nullptr);
154468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("jarray was NULL");
154568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1546289da82ae82438ab3aed1898c82fd87c16846e74Elliott Hughes}
1547289da82ae82438ab3aed1898c82fd87c16846e74Elliott Hughes
1548647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers#define EXPECT_STATIC_PRIMITIVE_FIELD(expect_eq, type, field_name, sig, value1, value2) \
1549885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  do { \
1550885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \
15512d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_NE(fid, nullptr); \
1552885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    env_->SetStatic ## type ## Field(c, fid, value1); \
1553647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers    expect_eq(value1, env_->GetStatic ## type ## Field(c, fid)); \
1554885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    env_->SetStatic ## type ## Field(c, fid, value2); \
1555647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers    expect_eq(value2, env_->GetStatic ## type ## Field(c, fid)); \
15562d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    \
155768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(false); \
155868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    { \
155968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      CheckJniAbortCatcher jni_abort_catcher; \
156068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      env_->GetStatic ## type ## Field(nullptr, fid); \
156168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      env_->SetStatic ## type ## Field(nullptr, fid, value1); \
156268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    } \
15632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CheckJniAbortCatcher jni_abort_catcher; \
15642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->GetStatic ## type ## Field(c, nullptr); \
15652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("fid == null"); \
15662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->SetStatic ## type ## Field(c, nullptr, value1); \
15672d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("fid == null"); \
156868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    \
156968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); \
157068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetStatic ## type ## Field(nullptr, fid); \
157168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("received NULL jclass"); \
157268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetStatic ## type ## Field(nullptr, fid, value1); \
157368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("received NULL jclass"); \
157468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetStatic ## type ## Field(c, nullptr); \
157568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("jfieldID was NULL"); \
157668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetStatic ## type ## Field(c, nullptr, value1); \
157768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("jfieldID was NULL"); \
157868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); \
1579885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  } while (false)
1580885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1581647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers#define EXPECT_PRIMITIVE_FIELD(expect_eq, instance, type, field_name, sig, value1, value2) \
1582885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  do { \
1583885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    jfieldID fid = env_->GetFieldID(c, field_name, sig); \
15842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_NE(fid, nullptr); \
1585885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    env_->Set ## type ## Field(instance, fid, value1); \
1586647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers    expect_eq(value1, env_->Get ## type ## Field(instance, fid)); \
1587885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    env_->Set ## type ## Field(instance, fid, value2); \
1588647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers    expect_eq(value2, env_->Get ## type ## Field(instance, fid)); \
15892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    \
159068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(false); \
15912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CheckJniAbortCatcher jni_abort_catcher; \
15922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->Get ## type ## Field(nullptr, fid); \
15932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("obj == null"); \
15942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->Set ## type ## Field(nullptr, fid, value1); \
15952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("obj == null"); \
15962d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->Get ## type ## Field(instance, nullptr); \
15972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("fid == null"); \
15982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->Set ## type ## Field(instance, nullptr, value1); \
15992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("fid == null"); \
160068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); \
160168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->Get ## type ## Field(nullptr, fid); \
160268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("field operation on NULL object:"); \
160368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->Set ## type ## Field(nullptr, fid, value1); \
160468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("field operation on NULL object:"); \
160568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->Get ## type ## Field(instance, nullptr); \
160668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("jfieldID was NULL"); \
160768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->Set ## type ## Field(instance, nullptr, value1); \
160868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("jfieldID was NULL"); \
160968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); \
1610885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  } while (false)
1611885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1612885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1613885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott HughesTEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) {
1614ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  TEST_DISABLED_FOR_PORTABLE();
161500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Thread::Current()->TransitionFromSuspendedToRunnable();
161600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  LoadDex("AllFields");
1617bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom  bool started = runtime_->Start();
16182d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(started);
1619885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1620885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jclass c = env_->FindClass("AllFields");
16212d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
1622885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jobject o = env_->AllocObject(c);
16232d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
1624885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1625647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Boolean, "sZ", "Z", JNI_TRUE, JNI_FALSE);
1626647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Byte, "sB", "B", 1, 2);
1627647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Char, "sC", "C", 'a', 'b');
1628647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_DOUBLE_EQ, Double, "sD", "D", 1.0, 2.0);
1629647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_FLOAT_EQ, Float, "sF", "F", 1.0, 2.0);
1630647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Int, "sI", "I", 1, 2);
1631647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Long, "sJ", "J", 1, 2);
1632647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Short, "sS", "S", 1, 2);
1633647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers
1634647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Boolean, "iZ", "Z", JNI_TRUE, JNI_FALSE);
1635647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Byte, "iB", "B", 1, 2);
1636647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Char, "iC", "C", 'a', 'b');
1637647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_DOUBLE_EQ, o, Double, "iD", "D", 1.0, 2.0);
1638647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_FLOAT_EQ, o, Float, "iF", "F", 1.0, 2.0);
1639647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Int, "iI", "I", 1, 2);
1640647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Long, "iJ", "J", 1, 2);
1641647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Short, "iS", "S", 1, 2);
1642885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes}
1643885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1644885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott HughesTEST_F(JniInternalTest, GetObjectField_SetObjectField) {
1645ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  TEST_DISABLED_FOR_PORTABLE();
164600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Thread::Current()->TransitionFromSuspendedToRunnable();
164700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  LoadDex("AllFields");
164825c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom  runtime_->Start();
1649885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1650885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jclass c = env_->FindClass("AllFields");
16512d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
1652885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jobject o = env_->AllocObject(c);
16532d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
1654885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1655885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jstring s1 = env_->NewStringUTF("hello");
16562d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s1, nullptr);
1657885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jstring s2 = env_->NewStringUTF("world");
16582d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s2, nullptr);
1659885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1660885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;");
16612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s_fid, nullptr);
1662885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;");
16632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(i_fid, nullptr);
1664885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1665885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  env_->SetStaticObjectField(c, s_fid, s1);
1666885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid)));
1667885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  env_->SetStaticObjectField(c, s_fid, s2);
1668885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid)));
1669885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1670885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  env_->SetObjectField(o, i_fid, s1);
1671885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid)));
1672885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  env_->SetObjectField(o, i_fid, s2);
1673885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid)));
1674885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes}
1675885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
16762d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, NewLocalRef_nullptr) {
16772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->NewLocalRef(nullptr), nullptr);
167818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
167918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
168018c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, NewLocalRef) {
168118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
16822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
168318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewLocalRef(s);
16842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, nullptr);
16852d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, s);
168618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
16872ced6a534157d5d963693346904389c19775d2daElliott Hughes  EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(o));
168818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
168918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
16902d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, DeleteLocalRef_nullptr) {
16912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->DeleteLocalRef(nullptr);
169218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
169318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
169418c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, DeleteLocalRef) {
169518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
16962d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
169718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteLocalRef(s);
169818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
16993f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes  // Currently, deleting an already-deleted reference is just a CheckJNI warning.
1700b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  {
170168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(false);
170268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    {
170368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      CheckJniAbortCatcher check_jni_abort_catcher;
170468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      env_->DeleteLocalRef(s);
170568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    }
1706b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    CheckJniAbortCatcher check_jni_abort_catcher;
170768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
1708b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    env_->DeleteLocalRef(s);
1709c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    std::string expected(StringPrintf("use of deleted local reference %p", s));
1710a9137c6bbdf4a1883f7b3f836c269eeb2ff619b2Elliott Hughes    check_jni_abort_catcher.Check(expected.c_str());
171168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1712b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
171318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
171418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  s = env_->NewStringUTF("");
17152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
171618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewLocalRef(s);
17172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
171818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
171918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteLocalRef(s);
172018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteLocalRef(o);
172118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
172218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
1723aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott HughesTEST_F(JniInternalTest, PushLocalFrame_10395422) {
1724aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // The JNI specification is ambiguous about whether the given capacity is to be interpreted as a
1725aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // maximum or as a minimum, but it seems like it's supposed to be a minimum, and that's how
1726aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // Android historically treated it, and it's how the RI treats it. It's also the more useful
1727aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // interpretation!
1728aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  ASSERT_EQ(JNI_OK, env_->PushLocalFrame(0));
17292d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->PopLocalFrame(nullptr);
1730aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes
1731aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // Negative capacities are not allowed.
1732aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(-1));
1733aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes
1734aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // And it's okay to have an upper limit. Ours is currently 512.
1735aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(8192));
1736aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes}
1737aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes
17382ced6a534157d5d963693346904389c19775d2daElliott HughesTEST_F(JniInternalTest, PushLocalFrame_PopLocalFrame) {
17392ced6a534157d5d963693346904389c19775d2daElliott Hughes  jobject original = env_->NewStringUTF("");
17402d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(original, nullptr);
17412ced6a534157d5d963693346904389c19775d2daElliott Hughes
17422ced6a534157d5d963693346904389c19775d2daElliott Hughes  jobject outer;
17432ced6a534157d5d963693346904389c19775d2daElliott Hughes  jobject inner1, inner2;
174400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(env_);
17452ced6a534157d5d963693346904389c19775d2daElliott Hughes  {
1746aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes    ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
17472ced6a534157d5d963693346904389c19775d2daElliott Hughes    outer = env_->NewLocalRef(original);
17482ced6a534157d5d963693346904389c19775d2daElliott Hughes
17492ced6a534157d5d963693346904389c19775d2daElliott Hughes    {
1750aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes      ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
17512ced6a534157d5d963693346904389c19775d2daElliott Hughes      inner1 = env_->NewLocalRef(outer);
17522ced6a534157d5d963693346904389c19775d2daElliott Hughes      inner2 = env_->NewStringUTF("survivor");
1753c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      EXPECT_NE(env_->PopLocalFrame(inner2), nullptr);
17542ced6a534157d5d963693346904389c19775d2daElliott Hughes    }
17552ced6a534157d5d963693346904389c19775d2daElliott Hughes
17562ced6a534157d5d963693346904389c19775d2daElliott Hughes    EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
17572ced6a534157d5d963693346904389c19775d2daElliott Hughes    EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(outer));
1758c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    {
1759c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      CheckJniAbortCatcher check_jni_abort_catcher;
1760c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
1761c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      check_jni_abort_catcher.Check("use of deleted local reference");
1762c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    }
17632ced6a534157d5d963693346904389c19775d2daElliott Hughes
17642ced6a534157d5d963693346904389c19775d2daElliott Hughes    // Our local reference for the survivor is invalid because the survivor
17652ced6a534157d5d963693346904389c19775d2daElliott Hughes    // gets a new local reference...
1766c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    {
1767c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      CheckJniAbortCatcher check_jni_abort_catcher;
1768c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
1769c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      check_jni_abort_catcher.Check("use of deleted local reference");
1770c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    }
17712ced6a534157d5d963693346904389c19775d2daElliott Hughes
1772c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    EXPECT_EQ(env_->PopLocalFrame(nullptr), nullptr);
17732ced6a534157d5d963693346904389c19775d2daElliott Hughes  }
17742ced6a534157d5d963693346904389c19775d2daElliott Hughes  EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
1775c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  CheckJniAbortCatcher check_jni_abort_catcher;
17762ced6a534157d5d963693346904389c19775d2daElliott Hughes  EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(outer));
1777c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  check_jni_abort_catcher.Check("use of deleted local reference");
17782ced6a534157d5d963693346904389c19775d2daElliott Hughes  EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
1779c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  check_jni_abort_catcher.Check("use of deleted local reference");
17802ced6a534157d5d963693346904389c19775d2daElliott Hughes  EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
1781c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  check_jni_abort_catcher.Check("use of deleted local reference");
17822ced6a534157d5d963693346904389c19775d2daElliott Hughes}
17832ced6a534157d5d963693346904389c19775d2daElliott Hughes
17842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, NewGlobalRef_nullptr) {
17852d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->NewGlobalRef(nullptr), nullptr);
178618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
178718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
178818c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, NewGlobalRef) {
178918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
17902d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
179118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewGlobalRef(s);
17922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, nullptr);
17932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, s);
179418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
17952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetObjectRefType(o), JNIGlobalRefType);
179618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
179718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
17982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, DeleteGlobalRef_nullptr) {
17992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->DeleteGlobalRef(nullptr);
180018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
180118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
180218c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, DeleteGlobalRef) {
180318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
18042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
180518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
180618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewGlobalRef(s);
18072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
180818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteGlobalRef(o);
180918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
18103f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes  // Currently, deleting an already-deleted reference is just a CheckJNI warning.
1811b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  {
181268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(false);
181368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    {
181468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      CheckJniAbortCatcher check_jni_abort_catcher;
181568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      env_->DeleteGlobalRef(o);
181668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    }
1817b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    CheckJniAbortCatcher check_jni_abort_catcher;
181868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
1819b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    env_->DeleteGlobalRef(o);
1820c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    std::string expected(StringPrintf("use of deleted global reference %p", o));
1821a9137c6bbdf4a1883f7b3f836c269eeb2ff619b2Elliott Hughes    check_jni_abort_catcher.Check(expected.c_str());
182268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1823b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
182418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
182518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o1 = env_->NewGlobalRef(s);
18262d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o1, nullptr);
182718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o2 = env_->NewGlobalRef(s);
18282d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o2, nullptr);
182918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
183018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteGlobalRef(o1);
183118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteGlobalRef(o2);
183218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
183318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
18342d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, NewWeakGlobalRef_nullptr) {
18352d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->NewWeakGlobalRef(nullptr),   nullptr);
183618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
183718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
183818c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, NewWeakGlobalRef) {
183918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
18402d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
184118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewWeakGlobalRef(s);
18422d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, nullptr);
18432d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, s);
184418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
18452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetObjectRefType(o), JNIWeakGlobalRefType);
184618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
184718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
18482d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, DeleteWeakGlobalRef_nullptr) {
18492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->DeleteWeakGlobalRef(nullptr);
185018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
185118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
185218c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, DeleteWeakGlobalRef) {
185318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
18542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
185518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
185618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewWeakGlobalRef(s);
18572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
185818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteWeakGlobalRef(o);
185918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
18603f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes  // Currently, deleting an already-deleted reference is just a CheckJNI warning.
1861b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  {
186268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(false);
186368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    {
186468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      CheckJniAbortCatcher check_jni_abort_catcher;
186568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      env_->DeleteWeakGlobalRef(o);
186668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    }
1867b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    CheckJniAbortCatcher check_jni_abort_catcher;
186868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
1869b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    env_->DeleteWeakGlobalRef(o);
1870c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    std::string expected(StringPrintf("use of deleted weak global reference %p", o));
1871a9137c6bbdf4a1883f7b3f836c269eeb2ff619b2Elliott Hughes    check_jni_abort_catcher.Check(expected.c_str());
187268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1873b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
187418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
187518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o1 = env_->NewWeakGlobalRef(s);
18762d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o1, nullptr);
187718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o2 = env_->NewWeakGlobalRef(s);
18782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o2, nullptr);
187918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
188018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteWeakGlobalRef(o1);
188118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteWeakGlobalRef(o2);
188218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
188318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
18843a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei ZavjalovTEST_F(JniInternalTest, ExceptionDescribe) {
18853a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov  // This checks how ExceptionDescribe handles call without exception.
18863a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov  env_->ExceptionClear();
18873a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov  env_->ExceptionDescribe();
18883a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov}
18893a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov
189037f7a40f6789bb287f287a9af00777af9d6428eeElliott HughesTEST_F(JniInternalTest, Throw) {
189137f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass exception_class = env_->FindClass("java/lang/RuntimeException");
18922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(exception_class != nullptr);
189337f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class));
18942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(exception != nullptr);
189537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
189637f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  EXPECT_EQ(JNI_OK, env_->Throw(exception));
189737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  EXPECT_TRUE(env_->ExceptionCheck());
1898a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes  jthrowable thrown_exception = env_->ExceptionOccurred();
189937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  env_->ExceptionClear();
1900a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes  EXPECT_TRUE(env_->IsSameObject(exception, thrown_exception));
190137f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
190268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  // Bad argument.
190368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
19042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(JNI_ERR, env_->Throw(nullptr));
190568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
190668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  CheckJniAbortCatcher check_jni_abort_catcher;
190768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(JNI_ERR, env_->Throw(nullptr));
190868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  check_jni_abort_catcher.Check("Throw received NULL jthrowable");
190968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
191068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers}
191137f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
191268d8b42ddec39ec0174162d90d4abaa004d1983eIan RogersTEST_F(JniInternalTest, ThrowNew) {
191337f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass exception_class = env_->FindClass("java/lang/RuntimeException");
19142d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(exception_class != nullptr);
191537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
19165cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  jthrowable thrown_exception;
19175cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes
191837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
191937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  EXPECT_TRUE(env_->ExceptionCheck());
19205cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  thrown_exception = env_->ExceptionOccurred();
19215cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  env_->ExceptionClear();
19225cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
19235cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes
19242d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, nullptr));
19255cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  EXPECT_TRUE(env_->ExceptionCheck());
19265cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  thrown_exception = env_->ExceptionOccurred();
192737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  env_->ExceptionClear();
1928a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
192968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
193068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  // Bad argument.
193168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
193268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  CheckJniAbortCatcher check_jni_abort_catcher;
193368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(JNI_ERR, env_->ThrowNew(nullptr, nullptr));
193468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  check_jni_abort_catcher.Check("c == null");
193568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
193668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(JNI_ERR, env_->ThrowNew(nullptr, nullptr));
193768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  check_jni_abort_catcher.Check("ThrowNew received NULL jclass");
193868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
193937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes}
194037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
19411d99e4549309d05007d041d058b1878de88e9585Ian RogersTEST_F(JniInternalTest, NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) {
19421d99e4549309d05007d041d058b1878de88e9585Ian Rogers  // Start runtime.
19431d99e4549309d05007d041d058b1878de88e9585Ian Rogers  Thread* self = Thread::Current();
19441d99e4549309d05007d041d058b1878de88e9585Ian Rogers  self->TransitionFromSuspendedToRunnable();
19451d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.lang.Class");
19461d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.lang.Object");
19471d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.DirectByteBuffer");
19481d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.MemoryBlock");
19491d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.MemoryBlock$UnmanagedBlock");
19501d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.MappedByteBuffer");
19511d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.ByteBuffer");
19521d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.Buffer");
19531d99e4549309d05007d041d058b1878de88e9585Ian Rogers  // TODO: we only load a dex file here as starting the runtime relies upon it.
19541d99e4549309d05007d041d058b1878de88e9585Ian Rogers  const char* class_name = "StaticLeafMethods";
19551d99e4549309d05007d041d058b1878de88e9585Ian Rogers  LoadDex(class_name);
19561d99e4549309d05007d041d058b1878de88e9585Ian Rogers  bool started = runtime_->Start();
19571d99e4549309d05007d041d058b1878de88e9585Ian Rogers  ASSERT_TRUE(started);
19581d99e4549309d05007d041d058b1878de88e9585Ian Rogers
1959b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jclass buffer_class = env_->FindClass("java/nio/Buffer");
19602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(buffer_class, nullptr);
1961b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1962b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  char bytes[1024];
1963b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes));
19642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(buffer, nullptr);
1965b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class));
19662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_EQ(env_->GetDirectBufferAddress(buffer), bytes);
19671ee99352d85a07558688365dba70e9aa8f476c03Ian Rogers  ASSERT_EQ(env_->GetDirectBufferCapacity(buffer), static_cast<jlong>(sizeof(bytes)));
196845d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom
196945d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom  {
197045d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom    CheckJniAbortCatcher check_jni_abort_catcher;
197185a93364e5111dc56a73eed0130856e66cab0802Brian Carlstrom    env_->NewDirectByteBuffer(bytes, static_cast<jlong>(INT_MAX) + 1);
197245d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom    check_jni_abort_catcher.Check("in call to NewDirectByteBuffer");
197345d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom  }
1974b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes}
1975b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
19766d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian RogersTEST_F(JniInternalTest, MonitorEnterExit) {
19772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Create an object to torture.
19786d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  jclass object_class = env_->FindClass("java/lang/Object");
19792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(object_class, nullptr);
19806d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  jobject object = env_->AllocObject(object_class);
19812d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(object, nullptr);
19826d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
19836d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Expected class of exceptions
19846d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  jclass imse_class = env_->FindClass("java/lang/IllegalMonitorStateException");
19852d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(imse_class, nullptr);
19866d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
19876d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  jthrowable thrown_exception;
19886d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
19896d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Unlock of unowned monitor
19906d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->MonitorExit(object);
19916d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_TRUE(env_->ExceptionCheck());
19926d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  thrown_exception = env_->ExceptionOccurred();
19936d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->ExceptionClear();
19946d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
19956d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
19966d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Lock of unowned monitor
19976d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->MonitorEnter(object);
19986d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
19996d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Regular unlock
20006d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->MonitorExit(object);
20016d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
20026d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
20036d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Recursively lock a lot
20046d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  size_t max_recursive_lock = 1024;
20056d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  for (size_t i = 0; i < max_recursive_lock; i++) {
20066d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    env_->MonitorEnter(object);
20076d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    EXPECT_FALSE(env_->ExceptionCheck());
20086d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  }
20096d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Recursively unlock a lot
20106d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  for (size_t i = 0; i < max_recursive_lock; i++) {
20116d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    env_->MonitorExit(object);
20126d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    EXPECT_FALSE(env_->ExceptionCheck());
20136d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  }
20146d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
20156d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Unlock of unowned monitor
20166d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->MonitorExit(object);
20176d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_TRUE(env_->ExceptionCheck());
20186d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  thrown_exception = env_->ExceptionOccurred();
20196d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->ExceptionClear();
20206d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
2021a92853eb60fbce1fa6d3bbd6a6013fb514fdf5cbElliott Hughes
20222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // It's an error to call MonitorEnter or MonitorExit on nullptr.
2023b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  {
2024b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    CheckJniAbortCatcher check_jni_abort_catcher;
20252d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->MonitorEnter(nullptr);
2026b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    check_jni_abort_catcher.Check("in call to MonitorEnter");
20272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->MonitorExit(nullptr);
2028b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    check_jni_abort_catcher.Check("in call to MonitorExit");
2029b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
20306d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers}
20316d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
20320cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers}  // namespace art
2033