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
19e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#include "art_method-inl.h"
20a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom#include "common_compiler_test.h"
21da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe#include "indirect_reference_table.h"
2268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers#include "java_vm_ext.h"
23da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe#include "jni_env_ext.h"
2456890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih#include "mirror/string-inl.h"
25e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "scoped_thread_state_change.h"
26726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes#include "ScopedLocalRef.h"
270c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes
280c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughesnamespace art {
290c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes
30a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom// TODO: Convert to CommonRuntimeTest. Currently MakeExecutable is used.
31a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromclass JniInternalTest : public CommonCompilerTest {
32c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott Hughes protected:
33c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott Hughes  virtual void SetUp() {
34a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    CommonCompilerTest::SetUp();
355174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
36a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes    vm_ = Runtime::Current()->GetJavaVM();
37a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes
385174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes    // Turn on -verbose:jni for the JNI tests.
39797136386d6c66289ba1d12cbf5b2ac32646bb90Ian Rogers    // gLogVerbosity.jni = true;
405174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
412d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    vm_->AttachCurrentThread(&env_, nullptr);
42b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
43ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    ScopedLocalRef<jclass> aioobe(env_,
44ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                                  env_->FindClass("java/lang/ArrayIndexOutOfBoundsException"));
452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK(aioobe.get() != nullptr);
46726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes    aioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(aioobe.get()));
47b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
48b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    ScopedLocalRef<jclass> ase(env_, env_->FindClass("java/lang/ArrayStoreException"));
492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK(ase.get() != nullptr);
50b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    ase_ = reinterpret_cast<jclass>(env_->NewGlobalRef(ase.get()));
51b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
52ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    ScopedLocalRef<jclass> sioobe(env_,
53ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                                  env_->FindClass("java/lang/StringIndexOutOfBoundsException"));
542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK(sioobe.get() != nullptr);
55726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes    sioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(sioobe.get()));
56726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes  }
57726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes
582d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  void ExpectException(jclass exception_class) {
5968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ScopedObjectAccess soa(env_);
6068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_TRUE(env_->ExceptionCheck())
6168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        << PrettyDescriptor(soa.Decode<mirror::Class*>(exception_class));
622d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jthrowable exception = env_->ExceptionOccurred();
632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_NE(nullptr, exception);
642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->ExceptionClear();
652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class));
662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  }
672d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
684d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom  void CleanUpJniEnv() {
692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (aioobe_ != nullptr) {
704d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom      env_->DeleteGlobalRef(aioobe_);
712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      aioobe_ = nullptr;
724d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom    }
732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (ase_ != nullptr) {
744d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom      env_->DeleteGlobalRef(ase_);
752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      ase_ = nullptr;
764d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom    }
772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (sioobe_ != nullptr) {
784d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom      env_->DeleteGlobalRef(sioobe_);
792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      sioobe_ = nullptr;
804d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom    }
814d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom  }
824d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom
8353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers  virtual void TearDown() OVERRIDE {
844d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom    CleanUpJniEnv();
85a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    CommonCompilerTest::TearDown();
86c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott Hughes  }
87b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
881d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jclass GetPrimitiveClass(char descriptor) {
891d99e4549309d05007d041d058b1878de88e9585Ian Rogers    ScopedObjectAccess soa(env_);
901d99e4549309d05007d041d058b1878de88e9585Ian Rogers    mirror::Class* c = class_linker_->FindPrimitiveClass(descriptor);
911d99e4549309d05007d041d058b1878de88e9585Ian Rogers    CHECK(c != nullptr);
921d99e4549309d05007d041d058b1878de88e9585Ian Rogers    return soa.AddLocalReference<jclass>(c);
931d99e4549309d05007d041d058b1878de88e9585Ian Rogers  }
941d99e4549309d05007d041d058b1878de88e9585Ian Rogers
9568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void ExpectClassFound(const char* name) {
9668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_NE(env_->FindClass(name), nullptr) << name;
9768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_FALSE(env_->ExceptionCheck()) << name;
9868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
9968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
10068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void ExpectClassNotFound(const char* name, bool check_jni, const char* check_jni_msg,
10168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                           CheckJniAbortCatcher* abort_catcher) {
10268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->FindClass(name), nullptr) << name;
10368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    if (!check_jni || check_jni_msg == nullptr) {
10468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_TRUE(env_->ExceptionCheck()) << name;
10568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      env_->ExceptionClear();
10668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    } else {
10768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      abort_catcher->Check(check_jni_msg);
10868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    }
10968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
11068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
11168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void FindClassTest(bool check_jni) {
11268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
11368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher check_jni_abort_catcher;
11468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
11568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // Null argument is always an abort.
11668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->FindClass(nullptr);
11768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
11868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "name == null");
11968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
12068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // Reference types...
12168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassFound("java/lang/String");
12268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // ...for arrays too, where you must include "L;".
12368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassFound("[Ljava/lang/String;");
12468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // Primitive arrays are okay too, if the primitive type is valid.
12568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassFound("[C");
12668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
12768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // But primitive types aren't allowed...
12868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassNotFound("C", check_jni, nullptr, &check_jni_abort_catcher);
12968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassNotFound("V", check_jni, nullptr, &check_jni_abort_catcher);
13068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassNotFound("K", check_jni, nullptr, &check_jni_abort_catcher);
13168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
13268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    if (check_jni) {
13368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      // Check JNI will reject invalid class names as aborts but without pending exceptions.
13468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_EQ(env_->FindClass("java.lang.String"), nullptr);
13568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_FALSE(env_->ExceptionCheck());
13668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      check_jni_abort_catcher.Check("illegal class name 'java.lang.String'");
13768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
13868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_EQ(env_->FindClass("[Ljava.lang.String;"), nullptr);
13968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_FALSE(env_->ExceptionCheck());
14068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      check_jni_abort_catcher.Check("illegal class name '[Ljava.lang.String;'");
14168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    } else {
14268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      // Without check JNI we're tolerant and replace '.' with '/'.
14368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      ExpectClassFound("java.lang.String");
14468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      ExpectClassFound("[Ljava.lang.String;");
14568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    }
14668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
14768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassNotFound("Ljava.lang.String;", check_jni, "illegal class name 'Ljava.lang.String;'",
14868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                        &check_jni_abort_catcher);
14968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassNotFound("[java.lang.String", check_jni, "illegal class name '[java.lang.String'",
15068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                        &check_jni_abort_catcher);
15168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
15268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // You can't include the "L;" in a JNI class descriptor.
15368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassNotFound("Ljava/lang/String;", check_jni, "illegal class name 'Ljava/lang/String;'",
15468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                        &check_jni_abort_catcher);
15568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
15668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // But you must include it for an array of any reference type.
15768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassNotFound("[java/lang/String", check_jni, "illegal class name '[java/lang/String'",
15868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                        &check_jni_abort_catcher);
15968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
16068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassNotFound("[K", check_jni, "illegal class name '[K'", &check_jni_abort_catcher);
16168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
16268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // Void arrays aren't allowed.
16368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassNotFound("[V", check_jni, "illegal class name '[V'", &check_jni_abort_catcher);
16468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
16568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
16668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
16768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
16868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void GetFieldIdBadArgumentTest(bool check_jni) {
16968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
17068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher check_jni_abort_catcher;
17168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
17268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass c = env_->FindClass("java/lang/String");
17368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_NE(c, nullptr);
17468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
17568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jfieldID fid = env_->GetFieldID(nullptr, "count", "I");
17668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, fid);
17768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "GetFieldID received NULL jclass"
17868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "java_class == null");
17968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    fid = env_->GetFieldID(c, nullptr, "I");
18068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, fid);
18168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
18268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "name == null");
18368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    fid = env_->GetFieldID(c, "count", nullptr);
18468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, fid);
18568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
18668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "sig == null");
18768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
18868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
18968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
19068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
19168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void GetStaticFieldIdBadArgumentTest(bool check_jni) {
19268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
19368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher check_jni_abort_catcher;
19468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
19568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass c = env_->FindClass("java/lang/String");
19668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_NE(c, nullptr);
19768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
19868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jfieldID fid = env_->GetStaticFieldID(nullptr, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
19968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, fid);
20068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "GetStaticFieldID received NULL jclass"
20168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "java_class == null");
20268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    fid = env_->GetStaticFieldID(c, nullptr, "Ljava/util/Comparator;");
20368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, fid);
20468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
20568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "name == null");
20668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", nullptr);
20768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, fid);
20868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
20968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "sig == null");
21068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
21168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
21268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
21368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
21468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void GetMethodIdBadArgumentTest(bool check_jni) {
21568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
21668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher check_jni_abort_catcher;
21768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
21868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jmethodID method = env_->GetMethodID(nullptr, "<init>", "(Ljava/lang/String;)V");
21968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, method);
22068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "GetMethodID received NULL jclass"
22168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "java_class == null");
22268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
22368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_TRUE(jlnsme != nullptr);
22468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    method = env_->GetMethodID(jlnsme, nullptr, "(Ljava/lang/String;)V");
22568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, method);
22668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
22768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "name == null");
22868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    method = env_->GetMethodID(jlnsme, "<init>", nullptr);
22968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, method);
23068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
23168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "sig == null");
23268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
23368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
23468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
23568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
23668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void GetStaticMethodIdBadArgumentTest(bool check_jni) {
23768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
23868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher check_jni_abort_catcher;
23968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
24068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jmethodID method = env_->GetStaticMethodID(nullptr, "valueOf", "(I)Ljava/lang/String;");
24168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, method);
24268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "GetStaticMethodID received NULL jclass"
24368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "java_class == null");
24468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass jlstring = env_->FindClass("java/lang/String");
24568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    method = env_->GetStaticMethodID(jlstring, nullptr, "(I)Ljava/lang/String;");
24668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, method);
24768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
24868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "name == null");
24968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    method = env_->GetStaticMethodID(jlstring, "valueOf", nullptr);
25068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, method);
25168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
25268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "sig == null");
25368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
25468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
25568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
25668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
25768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void GetFromReflectedField_ToReflectedFieldBadArgumentTest(bool check_jni) {
25868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
25968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher check_jni_abort_catcher;
26068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
26168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass c = env_->FindClass("java/lang/String");
26268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_NE(c, nullptr);
26368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jfieldID fid = env_->GetFieldID(c, "count", "I");
26468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_NE(fid, nullptr);
26568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
26668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // Check class argument for null argument, not checked in non-check JNI.
26768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jobject field = env_->ToReflectedField(nullptr, fid, JNI_FALSE);
26868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    if (check_jni) {
26968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_EQ(field, nullptr);
27068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      check_jni_abort_catcher.Check("ToReflectedField received NULL jclass");
27168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    } else {
27268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_NE(field, nullptr);
27368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    }
27468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
27568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    field = env_->ToReflectedField(c, nullptr, JNI_FALSE);
27668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(field, nullptr);
27768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "jfieldID was NULL"
27868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "fid == null");
27968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
28068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    fid = env_->FromReflectedField(nullptr);
28168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_EQ(fid, nullptr);
28268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "expected non-null java.lang.reflect.Field"
28368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "jlr_field == null");
28468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
28568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
28668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
28768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
28868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void GetFromReflectedMethod_ToReflectedMethodBadArgumentTest(bool check_jni) {
28968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
29068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher check_jni_abort_catcher;
29168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
29268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass c = env_->FindClass("java/lang/String");
29368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_NE(c, nullptr);
29468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jmethodID mid = env_->GetMethodID(c, "<init>", "()V");
29568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_NE(mid, nullptr);
29668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
29768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // Check class argument for null argument, not checked in non-check JNI.
29868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jobject method = env_->ToReflectedMethod(nullptr, mid, JNI_FALSE);
29968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    if (check_jni) {
30068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_EQ(method, nullptr);
30168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      check_jni_abort_catcher.Check("ToReflectedMethod received NULL jclass");
30268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    } else {
30368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_NE(method, nullptr);
30468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    }
30568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
30668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    method = env_->ToReflectedMethod(c, nullptr, JNI_FALSE);
30768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(method, nullptr);
30868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "jmethodID was NULL"
30968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "mid == null");
31068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    mid = env_->FromReflectedMethod(method);
31168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_EQ(mid, nullptr);
31268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "expected non-null method" : "jlr_method == null");
31368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
31468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
31568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
31668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
31768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void RegisterAndUnregisterNativesBadArguments(bool check_jni,
31868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                                CheckJniAbortCatcher* check_jni_abort_catcher) {
31968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
32068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // Passing a class of null is a failure.
32168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    {
32268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      JNINativeMethod methods[] = { };
32368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_EQ(env_->RegisterNatives(nullptr, methods, 0), JNI_ERR);
32468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      check_jni_abort_catcher->Check(check_jni ? "RegisterNatives received NULL jclass"
32568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                               : "java_class == null");
32668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    }
32768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
32868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // Passing methods as null is a failure.
32968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass jlobject = env_->FindClass("java/lang/Object");
33068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->RegisterNatives(jlobject, nullptr, 1), JNI_ERR);
33168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher->Check("methods == null");
33268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
33368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // Unregisters null is a failure.
33468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->UnregisterNatives(nullptr), JNI_ERR);
33568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher->Check(check_jni ? "UnregisterNatives received NULL jclass"
33668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                             : "java_class == null");
33768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
33868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
33968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
34068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
34168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
34268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void GetPrimitiveArrayElementsOfWrongType(bool check_jni) {
34368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
34468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher jni_abort_catcher;
34568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
34668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jbooleanArray array = env_->NewBooleanArray(10);
34768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jboolean is_copy;
34868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetByteArrayElements(reinterpret_cast<jbyteArray>(array), &is_copy), nullptr);
34968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
35068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected byte[]"
35168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get byte primitive array elements with an object of type boolean[]");
35268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetShortArrayElements(reinterpret_cast<jshortArray>(array), &is_copy), nullptr);
35368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
35468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected short[]"
35568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get short primitive array elements with an object of type boolean[]");
35668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetCharArrayElements(reinterpret_cast<jcharArray>(array), &is_copy), nullptr);
35768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
35868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected char[]"
35968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get char primitive array elements with an object of type boolean[]");
36068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetIntArrayElements(reinterpret_cast<jintArray>(array), &is_copy), nullptr);
36168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
36268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected int[]"
36368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get int primitive array elements with an object of type boolean[]");
36468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetLongArrayElements(reinterpret_cast<jlongArray>(array), &is_copy), nullptr);
36568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
36668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected long[]"
36768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get long primitive array elements with an object of type boolean[]");
36868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetFloatArrayElements(reinterpret_cast<jfloatArray>(array), &is_copy), nullptr);
36968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
37068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected float[]"
37168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get float primitive array elements with an object of type boolean[]");
37268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetDoubleArrayElements(reinterpret_cast<jdoubleArray>(array), &is_copy), nullptr);
37368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
37468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected double[]"
37568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get double primitive array elements with an object of type boolean[]");
37668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jbyteArray array2 = env_->NewByteArray(10);
37768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetBooleanArrayElements(reinterpret_cast<jbooleanArray>(array2), &is_copy),
37868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers              nullptr);
37968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
38068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type byte[] expected boolean[]"
38168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get boolean primitive array elements with an object of type byte[]");
38268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jobject object = env_->NewStringUTF("Test String");
38368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetBooleanArrayElements(reinterpret_cast<jbooleanArray>(object), &is_copy),
38468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers              nullptr);
38568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
38668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "jarray argument has non-array type: java.lang.String"
38768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        : "attempt to get boolean primitive array elements with an object of type java.lang.String");
38868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
38968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
39068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
39168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
39268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void ReleasePrimitiveArrayElementsOfWrongType(bool check_jni) {
39368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
39468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher jni_abort_catcher;
395dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers    {
396dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jbooleanArray array = env_->NewBooleanArray(10);
397dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      ASSERT_TRUE(array != nullptr);
398dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jboolean is_copy;
399dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jboolean* elements = env_->GetBooleanArrayElements(array, &is_copy);
400dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      ASSERT_TRUE(elements != nullptr);
401dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      env_->ReleaseByteArrayElements(reinterpret_cast<jbyteArray>(array),
402dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers                                     reinterpret_cast<jbyte*>(elements), 0);
403dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jni_abort_catcher.Check(
404dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers          check_jni ? "incompatible array type boolean[] expected byte[]"
405dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers              : "attempt to release byte primitive array elements with an object of type boolean[]");
406dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      env_->ReleaseShortArrayElements(reinterpret_cast<jshortArray>(array),
407dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers                                      reinterpret_cast<jshort*>(elements), 0);
408dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jni_abort_catcher.Check(
409dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers          check_jni ? "incompatible array type boolean[] expected short[]"
410dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers              : "attempt to release short primitive array elements with an object of type boolean[]");
411dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      env_->ReleaseCharArrayElements(reinterpret_cast<jcharArray>(array),
412dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers                                     reinterpret_cast<jchar*>(elements), 0);
413dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jni_abort_catcher.Check(
414dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers          check_jni ? "incompatible array type boolean[] expected char[]"
415dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers              : "attempt to release char primitive array elements with an object of type boolean[]");
416dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      env_->ReleaseIntArrayElements(reinterpret_cast<jintArray>(array),
417dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers                                    reinterpret_cast<jint*>(elements), 0);
418dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jni_abort_catcher.Check(
419dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers          check_jni ? "incompatible array type boolean[] expected int[]"
420dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers              : "attempt to release int primitive array elements with an object of type boolean[]");
421dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      env_->ReleaseLongArrayElements(reinterpret_cast<jlongArray>(array),
422dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers                                     reinterpret_cast<jlong*>(elements), 0);
423dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jni_abort_catcher.Check(
424dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers          check_jni ? "incompatible array type boolean[] expected long[]"
425dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers              : "attempt to release long primitive array elements with an object of type boolean[]");
426dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      env_->ReleaseFloatArrayElements(reinterpret_cast<jfloatArray>(array),
427dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers                                      reinterpret_cast<jfloat*>(elements), 0);
428dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jni_abort_catcher.Check(
429dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers          check_jni ? "incompatible array type boolean[] expected float[]"
430dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers              : "attempt to release float primitive array elements with an object of type boolean[]");
431dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      env_->ReleaseDoubleArrayElements(reinterpret_cast<jdoubleArray>(array),
432dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers                                       reinterpret_cast<jdouble*>(elements), 0);
433dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jni_abort_catcher.Check(
434dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers          check_jni ? "incompatible array type boolean[] expected double[]"
435dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers              : "attempt to release double primitive array elements with an object of type boolean[]");
436dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers
437dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      // Don't leak the elements array.
438dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      env_->ReleaseBooleanArrayElements(array, elements, 0);
439dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers    }
440dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers    {
441dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jbyteArray array = env_->NewByteArray(10);
442dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jboolean is_copy;
443dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jbyte* elements = env_->GetByteArrayElements(array, &is_copy);
444dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers
445dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      env_->ReleaseBooleanArrayElements(reinterpret_cast<jbooleanArray>(array),
446dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers                                        reinterpret_cast<jboolean*>(elements), 0);
447dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jni_abort_catcher.Check(
448dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers          check_jni ? "incompatible array type byte[] expected boolean[]"
449dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers              : "attempt to release boolean primitive array elements with an object of type byte[]");
450dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jobject object = env_->NewStringUTF("Test String");
451dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      env_->ReleaseBooleanArrayElements(reinterpret_cast<jbooleanArray>(object),
452dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers                                        reinterpret_cast<jboolean*>(elements), 0);
453dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jni_abort_catcher.Check(
454dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers          check_jni ? "jarray argument has non-array type: java.lang.String"
455dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers              : "attempt to release boolean primitive array elements with an object of type "
45668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers              "java.lang.String");
45768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
458dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      // Don't leak the elements array.
459dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      env_->ReleaseByteArrayElements(array, elements, 0);
460dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers    }
46168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
46268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
46368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
46468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void GetReleasePrimitiveArrayCriticalOfWrongType(bool check_jni) {
46568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
46668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher jni_abort_catcher;
46768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
46868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jobject object = env_->NewStringUTF("Test String");
46968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jboolean is_copy;
47068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    void* elements = env_->GetPrimitiveArrayCritical(reinterpret_cast<jarray>(object), &is_copy);
47168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String"
47268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        : "expected primitive array, given java.lang.String");
47368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->ReleasePrimitiveArrayCritical(reinterpret_cast<jarray>(object), elements, 0);
47468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String"
47568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        : "expected primitive array, given java.lang.String");
47668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
47768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
47868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
47968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
48068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void GetPrimitiveArrayRegionElementsOfWrongType(bool check_jni) {
48168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
48268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher jni_abort_catcher;
48368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    constexpr size_t kLength = 10;
48468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jbooleanArray array = env_->NewBooleanArray(kLength);
48568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_TRUE(array != nullptr);
48668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jboolean elements[kLength];
48768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetByteArrayRegion(reinterpret_cast<jbyteArray>(array), 0, kLength,
48868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                             reinterpret_cast<jbyte*>(elements));
48968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
49068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected byte[]"
49168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get region of byte primitive array elements with an object of type boolean[]");
49268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetShortArrayRegion(reinterpret_cast<jshortArray>(array), 0, kLength,
49368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                              reinterpret_cast<jshort*>(elements));
49468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
49568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected short[]"
49668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get region of short primitive array elements with an object of type boolean[]");
49768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetCharArrayRegion(reinterpret_cast<jcharArray>(array), 0, kLength,
49868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                             reinterpret_cast<jchar*>(elements));
49968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
50068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected char[]"
50168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get region of char primitive array elements with an object of type boolean[]");
50268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetIntArrayRegion(reinterpret_cast<jintArray>(array), 0, kLength,
50368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                            reinterpret_cast<jint*>(elements));
50468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
50568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected int[]"
50668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get region of int primitive array elements with an object of type boolean[]");
50768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetLongArrayRegion(reinterpret_cast<jlongArray>(array), 0, kLength,
50868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                             reinterpret_cast<jlong*>(elements));
50968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
51068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected long[]"
51168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get region of long primitive array elements with an object of type boolean[]");
51268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetFloatArrayRegion(reinterpret_cast<jfloatArray>(array), 0, kLength,
51368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                              reinterpret_cast<jfloat*>(elements));
51468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
51568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected float[]"
51668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get region of float primitive array elements with an object of type boolean[]");
51768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetDoubleArrayRegion(reinterpret_cast<jdoubleArray>(array), 0, kLength,
51868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                               reinterpret_cast<jdouble*>(elements));
51968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
52068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected double[]"
52168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get region of double primitive array elements with an object of type boolean[]");
52268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jbyteArray array2 = env_->NewByteArray(10);
52368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(array2), 0, kLength,
52468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                reinterpret_cast<jboolean*>(elements));
52568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
52668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type byte[] expected boolean[]"
52768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get region of boolean primitive array elements with an object of type byte[]");
52868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jobject object = env_->NewStringUTF("Test String");
52968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(object), 0, kLength,
53068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                reinterpret_cast<jboolean*>(elements));
53168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String"
53268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        : "attempt to get region of boolean primitive array elements with an object of type "
53368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers          "java.lang.String");
53468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
53568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
53668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
53768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
53868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void SetPrimitiveArrayRegionElementsOfWrongType(bool check_jni) {
53968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
54068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher jni_abort_catcher;
54168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    constexpr size_t kLength = 10;
54268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jbooleanArray array = env_->NewBooleanArray(kLength);
54368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_TRUE(array != nullptr);
54468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jboolean elements[kLength];
54568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetByteArrayRegion(reinterpret_cast<jbyteArray>(array), 0, kLength,
54668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                             reinterpret_cast<jbyte*>(elements));
54768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
54868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected byte[]"
54968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to set region of byte primitive array elements with an object of type boolean[]");
55068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetShortArrayRegion(reinterpret_cast<jshortArray>(array), 0, kLength,
55168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                              reinterpret_cast<jshort*>(elements));
55268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
55368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected short[]"
55468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to set region of short primitive array elements with an object of type boolean[]");
55568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetCharArrayRegion(reinterpret_cast<jcharArray>(array), 0, kLength,
55668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                             reinterpret_cast<jchar*>(elements));
55768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
55868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected char[]"
55968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to set region of char primitive array elements with an object of type boolean[]");
56068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetIntArrayRegion(reinterpret_cast<jintArray>(array), 0, kLength,
56168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                            reinterpret_cast<jint*>(elements));
56268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
56368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected int[]"
56468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to set region of int primitive array elements with an object of type boolean[]");
56568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetLongArrayRegion(reinterpret_cast<jlongArray>(array), 0, kLength,
56668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                             reinterpret_cast<jlong*>(elements));
56768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
56868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected long[]"
56968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to set region of long primitive array elements with an object of type boolean[]");
57068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetFloatArrayRegion(reinterpret_cast<jfloatArray>(array), 0, kLength,
57168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                              reinterpret_cast<jfloat*>(elements));
57268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
57368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected float[]"
57468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to set region of float primitive array elements with an object of type boolean[]");
57568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetDoubleArrayRegion(reinterpret_cast<jdoubleArray>(array), 0, kLength,
57668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                               reinterpret_cast<jdouble*>(elements));
57768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
57868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected double[]"
57968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to set region of double primitive array elements with an object of type boolean[]");
58068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jbyteArray array2 = env_->NewByteArray(10);
58168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(array2), 0, kLength,
58268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                reinterpret_cast<jboolean*>(elements));
58368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
58468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type byte[] expected boolean[]"
58568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to set region of boolean primitive array elements with an object of type byte[]");
58668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jobject object = env_->NewStringUTF("Test String");
58768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(object), 0, kLength,
58868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                reinterpret_cast<jboolean*>(elements));
58968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String"
59068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        : "attempt to set region of boolean primitive array elements with an object of type "
59168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers          "java.lang.String");
59268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
59368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
59468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
59568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void NewObjectArrayBadArguments(bool check_jni) {
59668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
59768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher jni_abort_catcher;
59868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
59968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass element_class = env_->FindClass("java/lang/String");
60068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_NE(element_class, nullptr);
60168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
60268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->NewObjectArray(-1, element_class, nullptr);
60368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(check_jni ? "negative jsize: -1" : "negative array length: -1");
60468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
60568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->NewObjectArray(std::numeric_limits<jint>::min(), element_class, nullptr);
60668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(check_jni ? "negative jsize: -2147483648"
60768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        : "negative array length: -2147483648");
60868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
60968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
61068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
61168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
6125f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe  void SetUpForTest(bool direct, const char* method_name, const char* method_sig,
6135f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe                    void* native_fnptr) {
6145f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe    // Initialize class loader and set generic JNI entrypoint.
6155f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe    // Note: this code is adapted from the jni_compiler_test, and taken with minimal modifications.
6165f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe    if (!runtime_->IsStarted()) {
6175f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe      {
6185f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe        ScopedObjectAccess soa(Thread::Current());
6195f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe        class_loader_ = LoadDex("MyClassNatives");
6205f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe        StackHandleScope<1> hs(soa.Self());
6215f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe        Handle<mirror::ClassLoader> loader(
6225f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe            hs.NewHandle(soa.Decode<mirror::ClassLoader*>(class_loader_)));
6235f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe        mirror::Class* c = class_linker_->FindClass(soa.Self(), "LMyClassNatives;", loader);
6245f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe        const auto pointer_size = class_linker_->GetImagePointerSize();
6255f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe        ArtMethod* method = direct ? c->FindDirectMethod(method_name, method_sig, pointer_size) :
6265f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe            c->FindVirtualMethod(method_name, method_sig, pointer_size);
6275f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe        ASSERT_TRUE(method != nullptr) << method_name << " " << method_sig;
6285f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe        method->SetEntryPointFromQuickCompiledCode(class_linker_->GetRuntimeQuickGenericJniStub());
6295f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe      }
6305f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe      // Start runtime.
6315f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe      Thread::Current()->TransitionFromSuspendedToRunnable();
6325f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe      bool started = runtime_->Start();
6335f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe      CHECK(started);
6345f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe    }
6355f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe    // JNI operations after runtime start.
6365f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe    env_ = Thread::Current()->GetJniEnv();
6375f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe    jklass_ = env_->FindClass("MyClassNatives");
6385f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe    ASSERT_TRUE(jklass_ != nullptr) << method_name << " " << method_sig;
6395f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe
6405f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe    if (direct) {
6415f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe      jmethod_ = env_->GetStaticMethodID(jklass_, method_name, method_sig);
6425f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe    } else {
6435f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe      jmethod_ = env_->GetMethodID(jklass_, method_name, method_sig);
6445f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe    }
6455f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe    ASSERT_TRUE(jmethod_ != nullptr) << method_name << " " << method_sig;
6465f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe
6475f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe    if (native_fnptr != nullptr) {
6485f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe      JNINativeMethod methods[] = { { method_name, method_sig, native_fnptr } };
6495f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe      ASSERT_EQ(JNI_OK, env_->RegisterNatives(jklass_, methods, 1))
6505f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe          << method_name << " " << method_sig;
6515f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe    } else {
6525f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe      env_->UnregisterNatives(jklass_);
6535f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe    }
6545f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe
6555f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe    jmethodID constructor = env_->GetMethodID(jklass_, "<init>", "()V");
6565f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe    jobj_ = env_->NewObject(jklass_, constructor);
6575f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe    ASSERT_TRUE(jobj_ != nullptr) << method_name << " " << method_sig;
6585f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe  }
6595f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe
660a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes  JavaVMExt* vm_;
6614d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom  JNIEnv* env_;
662814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  jclass aioobe_;
663b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  jclass ase_;
664b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jclass sioobe_;
6655f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe
6665f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe  jclass jklass_;
6675f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe  jobject jobj_;
6685f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe  jobject class_loader_;
6695f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe  jmethodID jmethod_;
6700c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes};
6710c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes
672885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott HughesTEST_F(JniInternalTest, AllocObject) {
673885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jclass c = env_->FindClass("java/lang/String");
6742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
675885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jobject o = env_->AllocObject(c);
6762d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
677885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
678885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  // We have an instance of the class we asked for...
679885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsInstanceOf(o, c));
680885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  // ...whose fields haven't been initialized because
681885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  // we didn't call a constructor.
682885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "count", "I")));
683885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes}
684885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
685c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott HughesTEST_F(JniInternalTest, GetVersion) {
686c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott Hughes  ASSERT_EQ(JNI_VERSION_1_6, env_->GetVersion());
687c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott Hughes}
688c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott Hughes
6890c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott HughesTEST_F(JniInternalTest, FindClass) {
690369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  // This tests leads to warnings in the log.
691369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  ScopedLogSeverity sls(LogSeverity::ERROR);
692369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe
69368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  FindClassTest(false);
69468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  FindClassTest(true);
6950c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes}
6960c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes
697cdf53120cd5a73cbedc1654e22542848468c0d2fElliott HughesTEST_F(JniInternalTest, GetFieldID) {
698cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
6992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(jlnsfe, nullptr);
700cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass c = env_->FindClass("java/lang/String");
7012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
702cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
703cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Wrong type.
704cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jfieldID fid = env_->GetFieldID(c, "count", "J");
7052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
7062d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
707cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
708b17d08b6ef0d36038e408dd79960293bb62ec1d9Ian Rogers  // Wrong type where type doesn't exist.
709b17d08b6ef0d36038e408dd79960293bb62ec1d9Ian Rogers  fid = env_->GetFieldID(c, "count", "Lrod/jane/freddy;");
7102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
7112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
712b17d08b6ef0d36038e408dd79960293bb62ec1d9Ian Rogers
713cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Wrong name.
714cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetFieldID(c, "Count", "I");
7152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
7162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
717cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
718cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Good declared field lookup.
719cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetFieldID(c, "count", "I");
7202d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(nullptr, fid);
721cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  EXPECT_FALSE(env_->ExceptionCheck());
722cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
723cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Good superclass field lookup.
724cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  c = env_->FindClass("java/lang/StringBuilder");
725cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetFieldID(c, "count", "I");
7262d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(nullptr, fid);
7272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(fid, nullptr);
728cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  EXPECT_FALSE(env_->ExceptionCheck());
729cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
730cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Not instance.
731cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
7322d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
7332d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
7342d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
7352d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Bad arguments.
73668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetFieldIdBadArgumentTest(false);
73768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetFieldIdBadArgumentTest(true);
738cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes}
739cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
740cdf53120cd5a73cbedc1654e22542848468c0d2fElliott HughesTEST_F(JniInternalTest, GetStaticFieldID) {
741cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
7422d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(jlnsfe, nullptr);
743cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass c = env_->FindClass("java/lang/String");
7442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
745cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
746cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Wrong type.
747cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J");
7482d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
7492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
750cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
751b17d08b6ef0d36038e408dd79960293bb62ec1d9Ian Rogers  // Wrong type where type doesn't exist.
752b17d08b6ef0d36038e408dd79960293bb62ec1d9Ian Rogers  fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Lrod/jane/freddy;");
7532d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
7542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
755b17d08b6ef0d36038e408dd79960293bb62ec1d9Ian Rogers
756cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Wrong name.
757cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
7582d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
7592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
760cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
761cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Good declared field lookup.
762cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
7632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(nullptr, fid);
7642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(fid, nullptr);
765cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  EXPECT_FALSE(env_->ExceptionCheck());
766cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
767cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Not static.
768cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetStaticFieldID(c, "count", "I");
7692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
7702d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
7712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
7722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Bad arguments.
77368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetStaticFieldIdBadArgumentTest(false);
77468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetStaticFieldIdBadArgumentTest(true);
775cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes}
776cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
7774dd71f1538a8d788c56c77378a59ce32afa519d7Ian RogersTEST_F(JniInternalTest, GetMethodID) {
7784dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlobject = env_->FindClass("java/lang/Object");
7794dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlstring = env_->FindClass("java/lang/String");
7804dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
781004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  jclass jncrbc = env_->FindClass("java/nio/channels/ReadableByteChannel");
7824dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
783004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  // Sanity check that no exceptions are pending.
784cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  ASSERT_FALSE(env_->ExceptionCheck());
7854dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
7864dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
787004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  // a pending exception.
7884dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jmethodID method = env_->GetMethodID(jlobject, "foo", "()V");
7892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, method);
7902d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsme);
7914dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
792004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  // Check that java.lang.Object.equals() does exist.
7934dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
7942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(nullptr, method);
7954dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
7964dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
7974dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // Check that GetMethodID for java.lang.String.valueOf(int) fails as the
798004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  // method is static.
7994dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
8002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, method);
8012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsme);
802ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom
803004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  // Check that GetMethodID for java.lang.NoSuchMethodError.<init>(String) finds the constructor.
804ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  method = env_->GetMethodID(jlnsme, "<init>", "(Ljava/lang/String;)V");
8052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(nullptr, method);
806ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_FALSE(env_->ExceptionCheck());
8072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
808004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  // Check that GetMethodID can find a interface method inherited from another interface.
809004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  method = env_->GetMethodID(jncrbc, "close", "()V");
810004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  EXPECT_NE(nullptr, method);
811004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  EXPECT_FALSE(env_->ExceptionCheck());
812004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom
8132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Bad arguments.
81468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetMethodIdBadArgumentTest(false);
81568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetMethodIdBadArgumentTest(true);
8164dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers}
8174dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
818a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu ChartierTEST_F(JniInternalTest, CallVoidMethodNullReceiver) {
819a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  jclass jlobject = env_->FindClass("java/lang/Object");
820a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  jmethodID method;
821a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier
822a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  // Check that GetMethodID for java.lang.NoSuchMethodError.<init>(String) finds the constructor.
823a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  method = env_->GetMethodID(jlobject, "<init>", "()V");
824a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  EXPECT_NE(nullptr, method);
825a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  EXPECT_FALSE(env_->ExceptionCheck());
826a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier
827a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  // Null object to CallVoidMethod.
828a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  CheckJniAbortCatcher check_jni_abort_catcher;
829a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  env_->CallVoidMethod(nullptr, method);
830a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  check_jni_abort_catcher.Check("null");
831a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier}
832a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier
8334dd71f1538a8d788c56c77378a59ce32afa519d7Ian RogersTEST_F(JniInternalTest, GetStaticMethodID) {
8344dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlobject = env_->FindClass("java/lang/Object");
8354dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
8364dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
8374dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // Sanity check that no exceptions are pending
838cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  ASSERT_FALSE(env_->ExceptionCheck());
8394dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
8404dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
8414dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // a pending exception
8424dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V");
8432d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, method);
8442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsme);
8454dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
8464dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as
8474dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // the method is not static
8484dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
8492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, method);
8502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsme);
8514dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
8524dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // Check that java.lang.String.valueOf(int) does exist
8534dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlstring = env_->FindClass("java/lang/String");
8542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  method = env_->GetStaticMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
8552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(nullptr, method);
8564dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
8572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
8582d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Bad arguments.
85968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetStaticMethodIdBadArgumentTest(false);
86068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetStaticMethodIdBadArgumentTest(true);
8614dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers}
8624dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
863cdf53120cd5a73cbedc1654e22542848468c0d2fElliott HughesTEST_F(JniInternalTest, FromReflectedField_ToReflectedField) {
864cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass jlrField = env_->FindClass("java/lang/reflect/Field");
865cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass c = env_->FindClass("java/lang/String");
8662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
867cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jfieldID fid = env_->GetFieldID(c, "count", "I");
8682d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(fid, nullptr);
869cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Turn the fid into a java.lang.reflect.Field...
870cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jobject field = env_->ToReflectedField(c, fid, JNI_FALSE);
87178959466de4e53d768d135ae301473cc7f4def99Mathieu Chartier  for (size_t i = 0; i <= kLocalsMax; ++i) {
87241da59665556e8dd5601178185c68d48d645500bMathieu Chartier    // Regression test for b/18396311, ToReflectedField leaking local refs causing a local
87341da59665556e8dd5601178185c68d48d645500bMathieu Chartier    // reference table overflows with 512 references to ArtField
87441da59665556e8dd5601178185c68d48d645500bMathieu Chartier    env_->DeleteLocalRef(env_->ToReflectedField(c, fid, JNI_FALSE));
87541da59665556e8dd5601178185c68d48d645500bMathieu Chartier  }
8762d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
877cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  ASSERT_TRUE(env_->IsInstanceOf(field, jlrField));
878cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // ...and back again.
879cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jfieldID fid2 = env_->FromReflectedField(field);
8802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(fid2, nullptr);
881ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  // Make sure we can actually use it.
882ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  jstring s = env_->NewStringUTF("poop");
883ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  ASSERT_EQ(4, env_->GetIntField(s, fid2));
8842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
8852d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Bad arguments.
88668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetFromReflectedField_ToReflectedFieldBadArgumentTest(false);
88768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetFromReflectedField_ToReflectedFieldBadArgumentTest(true);
888cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes}
889cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
890cdf53120cd5a73cbedc1654e22542848468c0d2fElliott HughesTEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
891cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass jlrMethod = env_->FindClass("java/lang/reflect/Method");
892d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(jlrMethod, nullptr);
893d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  jclass jlrConstructor = env_->FindClass("java/lang/reflect/Constructor");
894d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(jlrConstructor, nullptr);
895cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass c = env_->FindClass("java/lang/String");
8962d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
897d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz
898d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  jmethodID mid = env_->GetMethodID(c, "<init>", "()V");
8992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(mid, nullptr);
900d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  // Turn the mid into a java.lang.reflect.Constructor...
901cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
90278959466de4e53d768d135ae301473cc7f4def99Mathieu Chartier  for (size_t i = 0; i <= kLocalsMax; ++i) {
90341da59665556e8dd5601178185c68d48d645500bMathieu Chartier    // Regression test for b/18396311, ToReflectedMethod leaking local refs causing a local
90441da59665556e8dd5601178185c68d48d645500bMathieu Chartier    // reference table overflows with 512 references to ArtMethod
90541da59665556e8dd5601178185c68d48d645500bMathieu Chartier    env_->DeleteLocalRef(env_->ToReflectedMethod(c, mid, JNI_FALSE));
90641da59665556e8dd5601178185c68d48d645500bMathieu Chartier  }
907d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(method, nullptr);
908d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_TRUE(env_->IsInstanceOf(method, jlrConstructor));
909cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // ...and back again.
910cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jmethodID mid2 = env_->FromReflectedMethod(method);
9112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(mid2, nullptr);
912ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  // Make sure we can actually use it.
913d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  jstring s = reinterpret_cast<jstring>(env_->AllocObject(c));
914d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(s, nullptr);
915d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  env_->CallVoidMethod(s, mid2);
91639b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao  ASSERT_EQ(JNI_FALSE, env_->ExceptionCheck());
917848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao  env_->ExceptionClear();
918d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz
919d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  mid = env_->GetMethodID(c, "length", "()I");
920d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(mid, nullptr);
921d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  // Turn the mid into a java.lang.reflect.Method...
922d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
923d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(method, nullptr);
924d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod));
925d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  // ...and back again.
926d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  mid2 = env_->FromReflectedMethod(method);
927d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(mid2, nullptr);
928d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  // Make sure we can actually use it.
929d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  s = env_->NewStringUTF("poop");
930d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(s, nullptr);
9315d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers  ASSERT_EQ(4, env_->CallIntMethod(s, mid2));
9322d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
9332d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Bad arguments.
93468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetFromReflectedMethod_ToReflectedMethodBadArgumentTest(false);
93568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetFromReflectedMethod_ToReflectedMethodBadArgumentTest(true);
936cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes}
937cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
9382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogersstatic void BogusMethod() {
9392cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  // You can't pass null function pointers to RegisterNatives.
9405174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes}
9415174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
9422d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, RegisterAndUnregisterNatives) {
9434dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlobject = env_->FindClass("java/lang/Object");
9444dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
945fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  void* native_function = reinterpret_cast<void*>(BogusMethod);
9464dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
9472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Sanity check that no exceptions are pending.
948cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  ASSERT_FALSE(env_->ExceptionCheck());
9494dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
950369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  // The following can print errors to the log we'd like to ignore.
951fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  {
952369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    ScopedLogSeverity sls(LogSeverity::FATAL);
953369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    // Check that registering method without name causes a NoSuchMethodError.
954369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    {
955369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe      JNINativeMethod methods[] = { { nullptr, "()V", native_function } };
956369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe      EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
957369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    }
958369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    ExpectException(jlnsme);
959fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz
960369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    // Check that registering method without signature causes a NoSuchMethodError.
961369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    {
962369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe      JNINativeMethod methods[] = { { "notify", nullptr, native_function } };
963369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe      EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
964369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    }
965369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    ExpectException(jlnsme);
966fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz
967369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    // Check that registering method without function causes a NoSuchMethodError.
968369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    {
969369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe      JNINativeMethod methods[] = { { "notify", "()V", nullptr } };
970369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe      EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
971369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    }
972369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    ExpectException(jlnsme);
973fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz
974369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    // Check that registering to a non-existent java.lang.Object.foo() causes a NoSuchMethodError.
975369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    {
976369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe      JNINativeMethod methods[] = { { "foo", "()V", native_function } };
977369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe      EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
978369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    }
979369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    ExpectException(jlnsme);
9804dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
981369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    // Check that registering non-native methods causes a NoSuchMethodError.
982369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    {
983369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe      JNINativeMethod methods[] = { { "equals", "(Ljava/lang/Object;)Z", native_function } };
984369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe      EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
985369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    }
986369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    ExpectException(jlnsme);
9874dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  }
9884dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
9892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Check that registering native methods is successful.
9904dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  {
991fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz    JNINativeMethod methods[] = { { "notify", "()V", native_function } };
9922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_OK);
9932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  }
9942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
9952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->UnregisterNatives(jlobject), JNI_OK);
9962d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
9972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Check that registering no methods isn't a failure.
9982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  {
9992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    JNINativeMethod methods[] = { };
10002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 0), JNI_OK);
10012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  }
10022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
10032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->UnregisterNatives(jlobject), JNI_OK);
10042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
10052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Check that registering a -ve number of methods is a failure.
10062d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher check_jni_abort_catcher;
10072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  for (int i = -10; i < 0; ++i) {
10082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    JNINativeMethod methods[] = { };
10092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->RegisterNatives(jlobject, methods, i), JNI_ERR);
10102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    check_jni_abort_catcher.Check("negative method count: ");
10114dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  }
10124dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
10135174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
10142d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Unregistering a class with no natives is a warning.
10152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->UnregisterNatives(jlnsme), JNI_OK);
101668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
101768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  RegisterAndUnregisterNativesBadArguments(false, &check_jni_abort_catcher);
101868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  RegisterAndUnregisterNativesBadArguments(true, &check_jni_abort_catcher);
10194dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers}
10204dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
1021ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#define EXPECT_PRIMITIVE_ARRAY(new_fn, \
1022ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               get_region_fn, \
1023ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               set_region_fn, \
1024ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               get_elements_fn, \
1025ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               release_elements_fn, \
1026ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               scalar_type, \
1027ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               expected_class_descriptor) \
10282d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jsize size = 4; \
10292d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  \
10301d99e4549309d05007d041d058b1878de88e9585Ian Rogers  { \
10311d99e4549309d05007d041d058b1878de88e9585Ian Rogers    CheckJniAbortCatcher jni_abort_catcher; \
103268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    down_cast<JNIEnvExt*>(env_)->SetCheckJniEnabled(false); \
10331d99e4549309d05007d041d058b1878de88e9585Ian Rogers    /* Allocate an negative sized array and check it has the right failure type. */ \
10342d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->new_fn(-1), nullptr); \
10351d99e4549309d05007d041d058b1878de88e9585Ian Rogers    jni_abort_catcher.Check("negative array length: -1"); \
10362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->new_fn(std::numeric_limits<jint>::min()), nullptr); \
10371d99e4549309d05007d041d058b1878de88e9585Ian Rogers    jni_abort_catcher.Check("negative array length: -2147483648"); \
10382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    /* Pass the array as null. */ \
10392d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(0, env_->GetArrayLength(nullptr)); \
10402d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("java_array == null"); \
10412d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->get_region_fn(nullptr, 0, 0, nullptr); \
10422d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("java_array == null"); \
10432d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->set_region_fn(nullptr, 0, 0, nullptr); \
10442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("java_array == null"); \
10452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->get_elements_fn(nullptr, nullptr); \
10462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("java_array == null"); \
10472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->release_elements_fn(nullptr, nullptr, 0); \
10482d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("java_array == null"); \
10492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    /* Pass the elements for region as null. */ \
10502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    scalar_type ## Array a = env_->new_fn(size); \
10512d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->get_region_fn(a, 0, size, nullptr); \
10522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("buf == null"); \
10532d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->set_region_fn(a, 0, size, nullptr); \
10542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("buf == null"); \
105568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    down_cast<JNIEnvExt*>(env_)->SetCheckJniEnabled(true); \
10561d99e4549309d05007d041d058b1878de88e9585Ian Rogers  } \
1057814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Allocate an array and check it has the right type and length. */ \
1058814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  scalar_type ## Array a = env_->new_fn(size); \
10592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(a, nullptr); \
1060814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(a, env_->FindClass(expected_class_descriptor))); \
1061814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(size, env_->GetArrayLength(a)); \
1062d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
1063d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  /* GetPrimitiveArrayRegion/SetPrimitiveArrayRegion */ \
1064814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* AIOOBE for negative start offset. */ \
10652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->get_region_fn(a, -1, 1, nullptr); \
10662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
10672d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->set_region_fn(a, -1, 1, nullptr); \
10682d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
1069d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
1070814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* AIOOBE for negative length. */ \
10712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->get_region_fn(a, 0, -1, nullptr); \
10722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
10732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->set_region_fn(a, 0, -1, nullptr); \
10742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
1075d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
1076814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* AIOOBE for buffer overrun. */ \
10772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->get_region_fn(a, size - 1, size, nullptr); \
10782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
10792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->set_region_fn(a, size - 1, size, nullptr); \
10802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
1081d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
1082795e341fff6c1984a34667c971a7153a8d63eb23Vladimir Marko  /* Regression test against integer overflow in range check. */ \
1083795e341fff6c1984a34667c971a7153a8d63eb23Vladimir Marko  env_->get_region_fn(a, 0x7fffffff, 0x7fffffff, nullptr); \
1084795e341fff6c1984a34667c971a7153a8d63eb23Vladimir Marko  ExpectException(aioobe_); \
1085795e341fff6c1984a34667c971a7153a8d63eb23Vladimir Marko  env_->set_region_fn(a, 0x7fffffff, 0x7fffffff, nullptr); \
1086795e341fff6c1984a34667c971a7153a8d63eb23Vladimir Marko  ExpectException(aioobe_); \
1087795e341fff6c1984a34667c971a7153a8d63eb23Vladimir Marko  \
10882cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  /* It's okay for the buffer to be null as long as the length is 0. */ \
10892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->get_region_fn(a, 2, 0, nullptr); \
1090d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  /* Even if the offset is invalid... */ \
10912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->get_region_fn(a, 123, 0, nullptr); \
10922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
1093d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
10942cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  /* It's okay for the buffer to be null as long as the length is 0. */ \
10952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->set_region_fn(a, 2, 0, nullptr); \
1096d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  /* Even if the offset is invalid... */ \
10972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->set_region_fn(a, 123, 0, nullptr); \
10982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
1099d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
1100814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Prepare a couple of buffers. */ \
1101700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<scalar_type[]> src_buf(new scalar_type[size]); \
1102700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<scalar_type[]> dst_buf(new scalar_type[size]); \
1103814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  for (jsize i = 0; i < size; ++i) { src_buf[i] = scalar_type(i); } \
1104814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  for (jsize i = 0; i < size; ++i) { dst_buf[i] = scalar_type(-1); } \
1105d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
1106814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Copy all of src_buf onto the heap. */ \
1107ee0fa76b2e5d39ad36d1ff144b2d0270df81e606Elliott Hughes  env_->set_region_fn(a, 0, size, &src_buf[0]); \
1108814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Copy back only part. */ \
1109814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  env_->get_region_fn(a, 1, size - 2, &dst_buf[1]); \
1110ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_NE(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1111ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    << "short copy equal"; \
1112814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Copy the missing pieces. */ \
1113ee0fa76b2e5d39ad36d1ff144b2d0270df81e606Elliott Hughes  env_->get_region_fn(a, 0, 1, &dst_buf[0]); \
1114814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  env_->get_region_fn(a, size - 1, 1, &dst_buf[size - 1]); \
1115ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1116ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    << "fixed copy not equal"; \
1117814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Copy back the whole array. */ \
1118ee0fa76b2e5d39ad36d1ff144b2d0270df81e606Elliott Hughes  env_->get_region_fn(a, 0, size, &dst_buf[0]); \
1119ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1120ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    << "full copy not equal"; \
11217577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  /* GetPrimitiveArrayCritical */ \
11222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  void* v = env_->GetPrimitiveArrayCritical(a, nullptr); \
1123ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_EQ(memcmp(&src_buf[0], v, size * sizeof(scalar_type)), 0) \
1124ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    << "GetPrimitiveArrayCritical not equal"; \
11257577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleasePrimitiveArrayCritical(a, v, 0); \
11267577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  /* GetXArrayElements */ \
11272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  scalar_type* xs = env_->get_elements_fn(a, nullptr); \
1128ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_EQ(memcmp(&src_buf[0], xs, size * sizeof(scalar_type)), 0) \
1129ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    << # get_elements_fn " not equal"; \
11307577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->release_elements_fn(a, xs, 0); \
1131814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
1132814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, BooleanArrays) {
1133ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion,
1134ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetBooleanArrayElements, ReleaseBooleanArrayElements, jboolean, "[Z");
1135814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1136814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, ByteArrays) {
1137ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion,
1138ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetByteArrayElements, ReleaseByteArrayElements, jbyte, "[B");
1139814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1140814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, CharArrays) {
1141ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion,
1142ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetCharArrayElements, ReleaseCharArrayElements, jchar, "[C");
1143814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1144814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, DoubleArrays) {
1145ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion,
1146ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetDoubleArrayElements, ReleaseDoubleArrayElements, jdouble, "[D");
1147814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1148814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, FloatArrays) {
1149ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion,
1150ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetFloatArrayElements, ReleaseFloatArrayElements, jfloat, "[F");
1151814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1152814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, IntArrays) {
1153ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion,
1154ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetIntArrayElements, ReleaseIntArrayElements, jint, "[I");
1155814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1156814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, LongArrays) {
1157ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion,
1158ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetLongArrayElements, ReleaseLongArrayElements, jlong, "[J");
1159814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1160814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, ShortArrays) {
1161ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion,
1162ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetShortArrayElements, ReleaseShortArrayElements, jshort, "[S");
1163d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes}
1164d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes
11652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, GetPrimitiveArrayElementsOfWrongType) {
116668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetPrimitiveArrayElementsOfWrongType(false);
116768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetPrimitiveArrayElementsOfWrongType(true);
11682d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers}
11692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
11702d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, ReleasePrimitiveArrayElementsOfWrongType) {
117168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  ReleasePrimitiveArrayElementsOfWrongType(false);
117268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  ReleasePrimitiveArrayElementsOfWrongType(true);
11732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers}
117468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
11752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, GetReleasePrimitiveArrayCriticalOfWrongType) {
117668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetReleasePrimitiveArrayCriticalOfWrongType(false);
117768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetReleasePrimitiveArrayCriticalOfWrongType(true);
11782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers}
11792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
11802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, GetPrimitiveArrayRegionElementsOfWrongType) {
118168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetPrimitiveArrayRegionElementsOfWrongType(false);
118268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetPrimitiveArrayRegionElementsOfWrongType(true);
11832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers}
11842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
11852d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, SetPrimitiveArrayRegionElementsOfWrongType) {
118668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  SetPrimitiveArrayRegionElementsOfWrongType(false);
118768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  SetPrimitiveArrayRegionElementsOfWrongType(true);
11882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers}
11892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
1190f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott HughesTEST_F(JniInternalTest, NewObjectArray) {
1191bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  jclass element_class = env_->FindClass("java/lang/String");
11922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(element_class, nullptr);
1193bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  jclass array_class = env_->FindClass("[Ljava/lang/String;");
11942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(array_class, nullptr);
1195f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
11961d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jobjectArray a = env_->NewObjectArray(0, element_class, nullptr);
11972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(a, nullptr);
1198bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1199bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  EXPECT_EQ(0, env_->GetArrayLength(a));
1200f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
12011d99e4549309d05007d041d058b1878de88e9585Ian Rogers  a = env_->NewObjectArray(1, element_class, nullptr);
12022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(a, nullptr);
1203bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1204bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  EXPECT_EQ(1, env_->GetArrayLength(a));
12051d99e4549309d05007d041d058b1878de88e9585Ian Rogers  EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), nullptr));
12061d99e4549309d05007d041d058b1878de88e9585Ian Rogers
12072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Negative array length checks.
120868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  NewObjectArrayBadArguments(false);
120968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  NewObjectArrayBadArguments(true);
12101d99e4549309d05007d041d058b1878de88e9585Ian Rogers}
12111d99e4549309d05007d041d058b1878de88e9585Ian Rogers
12121d99e4549309d05007d041d058b1878de88e9585Ian RogersTEST_F(JniInternalTest, NewObjectArrayWithPrimitiveClasses) {
12131d99e4549309d05007d041d058b1878de88e9585Ian Rogers  const char* primitive_descriptors = "VZBSCIJFD";
12141d99e4549309d05007d041d058b1878de88e9585Ian Rogers  const char* primitive_names[] = {
12151d99e4549309d05007d041d058b1878de88e9585Ian Rogers      "void", "boolean", "byte", "short", "char", "int", "long", "float", "double"
12161d99e4549309d05007d041d058b1878de88e9585Ian Rogers  };
12171d99e4549309d05007d041d058b1878de88e9585Ian Rogers  ASSERT_EQ(strlen(primitive_descriptors), arraysize(primitive_names));
12181d99e4549309d05007d041d058b1878de88e9585Ian Rogers
121968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
12201d99e4549309d05007d041d058b1878de88e9585Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
12211d99e4549309d05007d041d058b1878de88e9585Ian Rogers  for (size_t i = 0; i < strlen(primitive_descriptors); ++i) {
12222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->NewObjectArray(0, nullptr, nullptr);
12232d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("element_jclass == null");
12241d99e4549309d05007d041d058b1878de88e9585Ian Rogers    jclass primitive_class = GetPrimitiveClass(primitive_descriptors[i]);
12251d99e4549309d05007d041d058b1878de88e9585Ian Rogers    env_->NewObjectArray(1, primitive_class, nullptr);
12261d99e4549309d05007d041d058b1878de88e9585Ian Rogers    std::string error_msg(StringPrintf("not an object type: %s", primitive_names[i]));
12271d99e4549309d05007d041d058b1878de88e9585Ian Rogers    jni_abort_catcher.Check(error_msg.c_str());
12281d99e4549309d05007d041d058b1878de88e9585Ian Rogers  }
122968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
123068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  for (size_t i = 0; i < strlen(primitive_descriptors); ++i) {
123168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->NewObjectArray(0, nullptr, nullptr);
123268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("NewObjectArray received NULL jclass");
123368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass primitive_class = GetPrimitiveClass(primitive_descriptors[i]);
123468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->NewObjectArray(1, primitive_class, nullptr);
123568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    std::string error_msg(StringPrintf("not an object type: %s", primitive_names[i]));
123668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(error_msg.c_str());
123768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
123868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
12391d99e4549309d05007d041d058b1878de88e9585Ian Rogers}
12401d99e4549309d05007d041d058b1878de88e9585Ian Rogers
12411d99e4549309d05007d041d058b1878de88e9585Ian RogersTEST_F(JniInternalTest, NewObjectArrayWithInitialValue) {
12421d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jclass element_class = env_->FindClass("java/lang/String");
12432d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(element_class, nullptr);
12441d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jclass array_class = env_->FindClass("[Ljava/lang/String;");
12452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(array_class, nullptr);
12467577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
12477577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jstring s = env_->NewStringUTF("poop");
12481d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jobjectArray a = env_->NewObjectArray(2, element_class, s);
12492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(a, nullptr);
12507577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
12517577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(2, env_->GetArrayLength(a));
12527577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), s));
12537577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 1), s));
12541d99e4549309d05007d041d058b1878de88e9585Ian Rogers
12551d99e4549309d05007d041d058b1878de88e9585Ian Rogers  // Attempt to incorrect create an array of strings with initial value of string arrays.
12561d99e4549309d05007d041d058b1878de88e9585Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
12571d99e4549309d05007d041d058b1878de88e9585Ian Rogers  env_->NewObjectArray(2, element_class, a);
12581d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jni_abort_catcher.Check("cannot assign object of type 'java.lang.String[]' to array with element "
12591d99e4549309d05007d041d058b1878de88e9585Ian Rogers                          "type of 'java.lang.String'");
1260bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes}
1261f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
1262bd9359912e5398799f60649b86ae80644ec72627Elliott HughesTEST_F(JniInternalTest, GetArrayLength) {
12632cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  // Already tested in NewObjectArray/NewPrimitiveArray except for null.
12642f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  CheckJniAbortCatcher jni_abort_catcher;
12652f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
12662f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  EXPECT_EQ(0, env_->GetArrayLength(nullptr));
12672f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  jni_abort_catcher.Check("java_array == null");
12682f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
12692f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  EXPECT_EQ(JNI_ERR, env_->GetArrayLength(nullptr));
12702f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  jni_abort_catcher.Check("jarray was NULL");
12712f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
12728a26c5c4c74b09e2887593c733a22652a9f80d7cElliott Hughes}
12738a26c5c4c74b09e2887593c733a22652a9f80d7cElliott Hughes
127437f7a40f6789bb287f287a9af00777af9d6428eeElliott HughesTEST_F(JniInternalTest, GetObjectClass) {
127537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass string_class = env_->FindClass("java/lang/String");
12762d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(string_class, nullptr);
127737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass class_class = env_->FindClass("java/lang/Class");
12782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(class_class, nullptr);
127937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
128037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jstring s = env_->NewStringUTF("poop");
128137f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass c = env_->GetObjectClass(s);
128237f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  ASSERT_TRUE(env_->IsSameObject(string_class, c));
128337f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
128437f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass c2 = env_->GetObjectClass(c);
128537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2)));
12862d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
12872d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Null as object should fail.
12882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
12892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetObjectClass(nullptr), nullptr);
12902d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_object == null");
129137f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes}
129237f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
1293885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott HughesTEST_F(JniInternalTest, GetSuperclass) {
1294885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jclass object_class = env_->FindClass("java/lang/Object");
12952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(object_class, nullptr);
1296885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jclass string_class = env_->FindClass("java/lang/String");
12972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(string_class, nullptr);
1298dc18020e83aa1261d4f661f1f9330bda20dffd71Ian Rogers  jclass runnable_interface = env_->FindClass("java/lang/Runnable");
12992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(runnable_interface, nullptr);
1300885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class)));
13012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_EQ(env_->GetSuperclass(object_class), nullptr);
130208ac922cf18e6a34a964a89031505395eeeeef2eBrian Carlstrom  ASSERT_EQ(env_->GetSuperclass(runnable_interface), nullptr);
13032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
13042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Null as class should fail.
13052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
130668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
13072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetSuperclass(nullptr), nullptr);
13082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_class == null");
130968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
131068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(env_->GetSuperclass(nullptr), nullptr);
131168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("GetSuperclass received NULL jclass");
131268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1313885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes}
1314885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
131537f7a40f6789bb287f287a9af00777af9d6428eeElliott HughesTEST_F(JniInternalTest, IsAssignableFrom) {
131637f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass object_class = env_->FindClass("java/lang/Object");
13172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(object_class, nullptr);
131837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass string_class = env_->FindClass("java/lang/String");
13192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(string_class, nullptr);
132037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
13211268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // A superclass is assignable from an instance of its
13221268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // subclass but not vice versa.
13231268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_TRUE(env_->IsAssignableFrom(string_class, object_class));
13241268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_FALSE(env_->IsAssignableFrom(object_class, string_class));
13251268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath
13261268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  jclass charsequence_interface = env_->FindClass("java/lang/CharSequence");
13271268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_NE(charsequence_interface, nullptr);
13281268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath
13291268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // An interface is assignable from an instance of an implementing
13301268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // class but not vice versa.
13311268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_TRUE(env_->IsAssignableFrom(string_class, charsequence_interface));
13321268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_FALSE(env_->IsAssignableFrom(charsequence_interface, string_class));
13331268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath
13341268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // Check that arrays are covariant.
13351268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  jclass string_array_class = env_->FindClass("[Ljava/lang/String;");
13361268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_NE(string_array_class, nullptr);
13371268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  jclass object_array_class = env_->FindClass("[Ljava/lang/Object;");
13381268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_NE(object_array_class, nullptr);
13391268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_TRUE(env_->IsAssignableFrom(string_array_class, object_array_class));
13401268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_FALSE(env_->IsAssignableFrom(object_array_class, string_array_class));
13411268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath
13421268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // Primitive types are tested in 004-JniTest.
13432d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
13442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Null as either class should fail.
13452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
134668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
13472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->IsAssignableFrom(nullptr, string_class), JNI_FALSE);
13482d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_class1 == null");
13492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->IsAssignableFrom(object_class, nullptr), JNI_FALSE);
13502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_class2 == null");
135168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
135268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(env_->IsAssignableFrom(nullptr, string_class), JNI_FALSE);
135368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("IsAssignableFrom received NULL jclass");
135468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(env_->IsAssignableFrom(object_class, nullptr), JNI_FALSE);
135568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("IsAssignableFrom received NULL jclass");
135668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
135737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes}
135837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
1359b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott HughesTEST_F(JniInternalTest, GetObjectRefType) {
1360b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jclass local = env_->FindClass("java/lang/Object");
13612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(local != nullptr);
1362b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(local));
1363b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1364b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jobject global = env_->NewGlobalRef(local);
1365b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ(JNIGlobalRefType, env_->GetObjectRefType(global));
1366b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1367b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jweak weak_global = env_->NewWeakGlobalRef(local);
1368b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ(JNIWeakGlobalRefType, env_->GetObjectRefType(weak_global));
1369b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1370a87630724ef4f8760684fa69c8ecc685735aff88Andreas Gampe  {
1371a87630724ef4f8760684fa69c8ecc685735aff88Andreas Gampe    CheckJniAbortCatcher jni_abort_catcher;
1372a87630724ef4f8760684fa69c8ecc685735aff88Andreas Gampe    jobject invalid = reinterpret_cast<jobject>(this);
1373a87630724ef4f8760684fa69c8ecc685735aff88Andreas Gampe    EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(invalid));
1374a87630724ef4f8760684fa69c8ecc685735aff88Andreas Gampe    jni_abort_catcher.Check("use of invalid jobject");
1375a87630724ef4f8760684fa69c8ecc685735aff88Andreas Gampe  }
1376b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1377b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  // TODO: invoke a native method and test that its arguments are considered local references.
13782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
1379a87630724ef4f8760684fa69c8ecc685735aff88Andreas Gampe  // Null as pointer should not fail and return invalid-ref. b/18820997
13802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(nullptr));
1381a87630724ef4f8760684fa69c8ecc685735aff88Andreas Gampe
1382a87630724ef4f8760684fa69c8ecc685735aff88Andreas Gampe  // TODO: Null as reference should return the original type.
1383a87630724ef4f8760684fa69c8ecc685735aff88Andreas Gampe  // This requires running a GC so a non-null object gets freed.
1384b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes}
1385b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
13860859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu ChartierTEST_F(JniInternalTest, StaleWeakGlobal) {
13870859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  jclass java_lang_Class = env_->FindClass("java/lang/Class");
13882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(java_lang_Class, nullptr);
13892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jobjectArray local_ref = env_->NewObjectArray(1, java_lang_Class, nullptr);
13902d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(local_ref, nullptr);
13910859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  jweak weak_global = env_->NewWeakGlobalRef(local_ref);
13922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(weak_global, nullptr);
13930859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  env_->DeleteLocalRef(local_ref);
13940859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  Runtime::Current()->GetHeap()->CollectGarbage(false);  // GC should clear the weak global.
13950859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  jobject new_global_ref = env_->NewGlobalRef(weak_global);
13962d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(new_global_ref, nullptr);
13970859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  jobject new_local_ref = env_->NewLocalRef(weak_global);
13982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(new_local_ref, nullptr);
13990859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier}
14000859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier
14018a26c5c4c74b09e2887593c733a22652a9f80d7cElliott HughesTEST_F(JniInternalTest, NewStringUTF) {
14022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->NewStringUTF(nullptr), nullptr);
1403814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  jstring s;
1404814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
1405814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  s = env_->NewStringUTF("");
14062d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(s, nullptr);
1407814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(0, env_->GetStringLength(s));
1408814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(0, env_->GetStringUTFLength(s));
1409814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  s = env_->NewStringUTF("hello");
14102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(s, nullptr);
1411814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(5, env_->GetStringLength(s));
1412814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(5, env_->GetStringUTFLength(s));
1413814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
1414a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  // Encoded surrogate pair.
1415a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  s = env_->NewStringUTF("\xed\xa0\x81\xed\xb0\x80");
1416a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  EXPECT_NE(s, nullptr);
1417a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  EXPECT_EQ(2, env_->GetStringLength(s));
1418e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath
1419e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  // The surrogate pair gets encoded into a 4 byte UTF sequence..
1420e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  EXPECT_EQ(4, env_->GetStringUTFLength(s));
1421a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  const char* chars = env_->GetStringUTFChars(s, nullptr);
1422e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  EXPECT_STREQ("\xf0\x90\x90\x80", chars);
1423a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  env_->ReleaseStringUTFChars(s, chars);
1424a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath
1425e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  // .. but is stored as is in the utf-16 representation.
1426e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  const jchar* jchars = env_->GetStringChars(s, nullptr);
1427e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  EXPECT_EQ(0xd801, jchars[0]);
1428e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  EXPECT_EQ(0xdc00, jchars[1]);
1429e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  env_->ReleaseStringChars(s, jchars);
1430e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath
1431a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  // 4 byte UTF sequence appended to an encoded surrogate pair.
1432a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  s = env_->NewStringUTF("\xed\xa0\x81\xed\xb0\x80 \xf0\x9f\x8f\xa0");
1433a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  EXPECT_NE(s, nullptr);
1434e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath
1435e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  // The 4 byte sequence {0xf0, 0x9f, 0x8f, 0xa0} is converted into a surrogate
1436e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  // pair {0xd83c, 0xdfe0}.
1437a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  EXPECT_EQ(5, env_->GetStringLength(s));
1438e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  jchars = env_->GetStringChars(s, nullptr);
1439e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  // The first surrogate pair, encoded as such in the input.
1440e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  EXPECT_EQ(0xd801, jchars[0]);
1441e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  EXPECT_EQ(0xdc00, jchars[1]);
1442e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  // The second surrogate pair, from the 4 byte UTF sequence in the input.
1443e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  EXPECT_EQ(0xd83c, jchars[3]);
1444e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  EXPECT_EQ(0xdfe0, jchars[4]);
1445e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  env_->ReleaseStringChars(s, jchars);
1446e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath
1447e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  EXPECT_EQ(9, env_->GetStringUTFLength(s));
1448a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  chars = env_->GetStringUTFChars(s, nullptr);
1449e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  EXPECT_STREQ("\xf0\x90\x90\x80 \xf0\x9f\x8f\xa0", chars);
1450a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  env_->ReleaseStringUTFChars(s, chars);
1451a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath
1452a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  // A string with 1, 2, 3 and 4 byte UTF sequences with spaces
1453a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  // between them
1454a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  s = env_->NewStringUTF("\x24 \xc2\xa2 \xe2\x82\xac \xf0\x9f\x8f\xa0");
1455a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  EXPECT_NE(s, nullptr);
1456a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  EXPECT_EQ(8, env_->GetStringLength(s));
1457e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  EXPECT_EQ(13, env_->GetStringUTFLength(s));
1458814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1459814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
1460814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, NewString) {
1461814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  jchar chars[] = { 'h', 'i' };
1462814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  jstring s;
1463814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  s = env_->NewString(chars, 0);
14642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(s, nullptr);
1465814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(0, env_->GetStringLength(s));
1466814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(0, env_->GetStringUTFLength(s));
1467814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  s = env_->NewString(chars, 2);
14682d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(s, nullptr);
1469814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(2, env_->GetStringLength(s));
1470814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(2, env_->GetStringUTFLength(s));
1471814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
14728a26c5c4c74b09e2887593c733a22652a9f80d7cElliott Hughes  // TODO: check some non-ASCII strings.
1473f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes}
1474f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
147525e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse WilsonTEST_F(JniInternalTest, NewStringNullCharsZeroLength) {
14761d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jstring s = env_->NewString(nullptr, 0);
14772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(s, nullptr);
147825e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse Wilson  EXPECT_EQ(0, env_->GetStringLength(s));
147925e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse Wilson}
148025e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse Wilson
14811d99e4549309d05007d041d058b1878de88e9585Ian RogersTEST_F(JniInternalTest, NewStringNullCharsNonzeroLength) {
14821d99e4549309d05007d041d058b1878de88e9585Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
14831d99e4549309d05007d041d058b1878de88e9585Ian Rogers  env_->NewString(nullptr, 1);
14841d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jni_abort_catcher.Check("chars == null && char_count > 0");
14851d99e4549309d05007d041d058b1878de88e9585Ian Rogers}
14861d99e4549309d05007d041d058b1878de88e9585Ian Rogers
14871d99e4549309d05007d041d058b1878de88e9585Ian RogersTEST_F(JniInternalTest, NewStringNegativeLength) {
14881d99e4549309d05007d041d058b1878de88e9585Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
148968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
14901d99e4549309d05007d041d058b1878de88e9585Ian Rogers  env_->NewString(nullptr, -1);
14911d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jni_abort_catcher.Check("char_count < 0: -1");
14921d99e4549309d05007d041d058b1878de88e9585Ian Rogers  env_->NewString(nullptr, std::numeric_limits<jint>::min());
14931d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jni_abort_catcher.Check("char_count < 0: -2147483648");
149468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
149568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  env_->NewString(nullptr, -1);
149668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("negative jsize: -1");
149768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  env_->NewString(nullptr, std::numeric_limits<jint>::min());
149868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("negative jsize: -2147483648");
149968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
150025e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse Wilson}
150125e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse Wilson
1502b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott HughesTEST_F(JniInternalTest, GetStringLength_GetStringUTFLength) {
1503b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  // Already tested in the NewString/NewStringUTF tests.
1504b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes}
1505b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1506b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott HughesTEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) {
1507b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jstring s = env_->NewStringUTF("hello");
15082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(s != nullptr);
1509b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
15102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, -1, 0, nullptr);
15112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
15122d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, 0, -1, nullptr);
15132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
15142d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, 0, 10, nullptr);
15152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
15162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, 10, 1, nullptr);
15172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
1518795e341fff6c1984a34667c971a7153a8d63eb23Vladimir Marko  // Regression test against integer overflow in range check.
1519795e341fff6c1984a34667c971a7153a8d63eb23Vladimir Marko  env_->GetStringRegion(s, 0x7fffffff, 0x7fffffff, nullptr);
1520795e341fff6c1984a34667c971a7153a8d63eb23Vladimir Marko  ExpectException(sioobe_);
1521b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1522b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jchar chars[4] = { 'x', 'x', 'x', 'x' };
1523b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  env_->GetStringRegion(s, 1, 2, &chars[1]);
1524b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('x', chars[0]);
1525b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('e', chars[1]);
1526b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('l', chars[2]);
1527b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('x', chars[3]);
1528b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
15292cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  // It's okay for the buffer to be null as long as the length is 0.
15302d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, 2, 0, nullptr);
1531d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  // Even if the offset is invalid...
15322d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, 123, 0, nullptr);
15332d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
15342d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
15352d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, -1, 0, nullptr);
15362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
15372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, 0, -1, nullptr);
15382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
15392d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, 0, 10, nullptr);
15402d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
15412d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, 10, 1, nullptr);
15422d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
1543795e341fff6c1984a34667c971a7153a8d63eb23Vladimir Marko  // Regression test against integer overflow in range check.
1544795e341fff6c1984a34667c971a7153a8d63eb23Vladimir Marko  env_->GetStringUTFRegion(s, 0x7fffffff, 0x7fffffff, nullptr);
1545795e341fff6c1984a34667c971a7153a8d63eb23Vladimir Marko  ExpectException(sioobe_);
1546b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1547b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  char bytes[4] = { 'x', 'x', 'x', 'x' };
1548b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  env_->GetStringUTFRegion(s, 1, 2, &bytes[1]);
1549b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('x', bytes[0]);
1550b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('e', bytes[1]);
1551b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('l', bytes[2]);
1552b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('x', bytes[3]);
1553d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes
15542cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  // It's okay for the buffer to be null as long as the length is 0.
15552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, 2, 0, nullptr);
1556d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  // Even if the offset is invalid...
15572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, 123, 0, nullptr);
15582d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
1559b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes}
1560b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
15617577075b147fd8fa37ca41e7a32d1124676776ceElliott HughesTEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) {
15622cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  // Passing in a null jstring is ignored normally, but caught by -Xcheck:jni.
156368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
1564b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  {
1565b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    CheckJniAbortCatcher check_jni_abort_catcher;
15662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->GetStringUTFChars(nullptr, nullptr), nullptr);
156768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
156868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  {
156968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher check_jni_abort_catcher;
157068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
157168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetStringUTFChars(nullptr, nullptr), nullptr);
157268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check("GetStringUTFChars received NULL jstring");
157368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1574b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
15757577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
15767577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jstring s = env_->NewStringUTF("hello");
15772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(s != nullptr);
15787577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
15792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  const char* utf = env_->GetStringUTFChars(s, nullptr);
15807577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_STREQ("hello", utf);
15817577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringUTFChars(s, utf);
15827577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
15837577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jboolean is_copy = JNI_FALSE;
15847577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  utf = env_->GetStringUTFChars(s, &is_copy);
15857577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(JNI_TRUE, is_copy);
15867577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_STREQ("hello", utf);
15877577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringUTFChars(s, utf);
15887577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes}
15897577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
15907577075b147fd8fa37ca41e7a32d1124676776ceElliott HughesTEST_F(JniInternalTest, GetStringChars_ReleaseStringChars) {
15917577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jstring s = env_->NewStringUTF("hello");
159256890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  ScopedObjectAccess soa(env_);
159356890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  mirror::String* s_m = soa.Decode<mirror::String*>(s);
15942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(s != nullptr);
15957577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
15967577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
15972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  const jchar* chars = env_->GetStringChars(s, nullptr);
15987577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[0], chars[0]);
15997577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[1], chars[1]);
16007577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[2], chars[2]);
16017577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[3], chars[3]);
16027577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[4], chars[4]);
16037577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringChars(s, chars);
16047577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
16057577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jboolean is_copy = JNI_FALSE;
16067577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  chars = env_->GetStringChars(s, &is_copy);
1607848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao  if (Runtime::Current()->GetHeap()->IsMovableObject(s_m)) {
160856890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    EXPECT_EQ(JNI_TRUE, is_copy);
160956890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  } else {
161056890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    EXPECT_EQ(JNI_FALSE, is_copy);
161156890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  }
16127577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[0], chars[0]);
16137577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[1], chars[1]);
16147577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[2], chars[2]);
16157577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[3], chars[3]);
16167577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[4], chars[4]);
16177577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringChars(s, chars);
16187577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes}
16197577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
16207577075b147fd8fa37ca41e7a32d1124676776ceElliott HughesTEST_F(JniInternalTest, GetStringCritical_ReleaseStringCritical) {
16217577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jstring s = env_->NewStringUTF("hello");
16222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(s != nullptr);
16237577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
16247577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
16252d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  const jchar* chars = env_->GetStringCritical(s, nullptr);
16267577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[0], chars[0]);
16277577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[1], chars[1]);
16287577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[2], chars[2]);
16297577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[3], chars[3]);
16307577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[4], chars[4]);
16317577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringCritical(s, chars);
16327577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
163356890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  jboolean is_copy = JNI_TRUE;
16347577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  chars = env_->GetStringCritical(s, &is_copy);
163556890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  EXPECT_EQ(JNI_FALSE, is_copy);
16367577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[0], chars[0]);
16377577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[1], chars[1]);
16387577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[2], chars[2]);
16397577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[3], chars[3]);
16407577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[4], chars[4]);
16417577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringCritical(s, chars);
16427577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes}
16437577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
1644814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) {
1645b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  jclass java_lang_Class = env_->FindClass("java/lang/Class");
16462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(java_lang_Class != nullptr);
1647289da82ae82438ab3aed1898c82fd87c16846e74Elliott Hughes
16482d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jobjectArray array = env_->NewObjectArray(1, java_lang_Class, nullptr);
16492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(array, nullptr);
16502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetObjectArrayElement(array, 0), nullptr);
1651b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  env_->SetObjectArrayElement(array, 0, java_lang_Class);
1652b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), java_lang_Class));
1653a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes
1654a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes  // ArrayIndexOutOfBounds for negative index.
1655b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  env_->SetObjectArrayElement(array, -1, java_lang_Class);
16562d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_);
1657a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes
1658a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes  // ArrayIndexOutOfBounds for too-large index.
1659b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  env_->SetObjectArrayElement(array, 1, java_lang_Class);
16602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_);
1661a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes
1662b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  // ArrayStoreException thrown for bad types.
1663b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  env_->SetObjectArrayElement(array, 0, env_->NewStringUTF("not a jclass!"));
16642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(ase_);
16652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
16662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Null as array should fail.
16672d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
166868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
16692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, env_->GetObjectArrayElement(nullptr, 0));
16702d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_array == null");
16712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->SetObjectArrayElement(nullptr, 0, nullptr);
16722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_array == null");
167368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
167468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(nullptr, env_->GetObjectArrayElement(nullptr, 0));
167568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("jarray was NULL");
167668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  env_->SetObjectArrayElement(nullptr, 0, nullptr);
167768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("jarray was NULL");
167868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1679289da82ae82438ab3aed1898c82fd87c16846e74Elliott Hughes}
1680289da82ae82438ab3aed1898c82fd87c16846e74Elliott Hughes
1681647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers#define EXPECT_STATIC_PRIMITIVE_FIELD(expect_eq, type, field_name, sig, value1, value2) \
1682885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  do { \
1683885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \
16842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_NE(fid, nullptr); \
1685885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    env_->SetStatic ## type ## Field(c, fid, value1); \
1686647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers    expect_eq(value1, env_->GetStatic ## type ## Field(c, fid)); \
1687885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    env_->SetStatic ## type ## Field(c, fid, value2); \
1688647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers    expect_eq(value2, env_->GetStatic ## type ## Field(c, fid)); \
16892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    \
169068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(false); \
169168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    { \
169268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      CheckJniAbortCatcher jni_abort_catcher; \
169368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      env_->GetStatic ## type ## Field(nullptr, fid); \
169468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      env_->SetStatic ## type ## Field(nullptr, fid, value1); \
169568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    } \
16962d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CheckJniAbortCatcher jni_abort_catcher; \
16972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->GetStatic ## type ## Field(c, nullptr); \
16982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("fid == null"); \
16992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->SetStatic ## type ## Field(c, nullptr, value1); \
17002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("fid == null"); \
170168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    \
170268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); \
170368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetStatic ## type ## Field(nullptr, fid); \
170468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("received NULL jclass"); \
170568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetStatic ## type ## Field(nullptr, fid, value1); \
170668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("received NULL jclass"); \
170768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetStatic ## type ## Field(c, nullptr); \
170868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("jfieldID was NULL"); \
170968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetStatic ## type ## Field(c, nullptr, value1); \
171068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("jfieldID was NULL"); \
171168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); \
1712885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  } while (false)
1713885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1714647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers#define EXPECT_PRIMITIVE_FIELD(expect_eq, instance, type, field_name, sig, value1, value2) \
1715885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  do { \
1716885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    jfieldID fid = env_->GetFieldID(c, field_name, sig); \
17172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_NE(fid, nullptr); \
1718885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    env_->Set ## type ## Field(instance, fid, value1); \
1719647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers    expect_eq(value1, env_->Get ## type ## Field(instance, fid)); \
1720885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    env_->Set ## type ## Field(instance, fid, value2); \
1721647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers    expect_eq(value2, env_->Get ## type ## Field(instance, fid)); \
17222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    \
172368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(false); \
17242d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CheckJniAbortCatcher jni_abort_catcher; \
17252d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->Get ## type ## Field(nullptr, fid); \
17262d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("obj == null"); \
17272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->Set ## type ## Field(nullptr, fid, value1); \
17282d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("obj == null"); \
17292d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->Get ## type ## Field(instance, nullptr); \
17302d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("fid == null"); \
17312d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->Set ## type ## Field(instance, nullptr, value1); \
17322d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("fid == null"); \
173368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); \
173468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->Get ## type ## Field(nullptr, fid); \
173568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("field operation on NULL object:"); \
173668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->Set ## type ## Field(nullptr, fid, value1); \
173768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("field operation on NULL object:"); \
173868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->Get ## type ## Field(instance, nullptr); \
173968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("jfieldID was NULL"); \
174068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->Set ## type ## Field(instance, nullptr, value1); \
174168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("jfieldID was NULL"); \
174268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); \
1743885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  } while (false)
1744885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1745885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1746885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott HughesTEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) {
174700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Thread::Current()->TransitionFromSuspendedToRunnable();
174800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  LoadDex("AllFields");
1749bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom  bool started = runtime_->Start();
17502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(started);
1751885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1752885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jclass c = env_->FindClass("AllFields");
17532d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
1754885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jobject o = env_->AllocObject(c);
17552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
1756885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1757647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Boolean, "sZ", "Z", JNI_TRUE, JNI_FALSE);
1758647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Byte, "sB", "B", 1, 2);
1759647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Char, "sC", "C", 'a', 'b');
1760647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_DOUBLE_EQ, Double, "sD", "D", 1.0, 2.0);
1761647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_FLOAT_EQ, Float, "sF", "F", 1.0, 2.0);
1762647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Int, "sI", "I", 1, 2);
1763647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Long, "sJ", "J", 1, 2);
1764647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Short, "sS", "S", 1, 2);
1765647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers
1766647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Boolean, "iZ", "Z", JNI_TRUE, JNI_FALSE);
1767647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Byte, "iB", "B", 1, 2);
1768647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Char, "iC", "C", 'a', 'b');
1769647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_DOUBLE_EQ, o, Double, "iD", "D", 1.0, 2.0);
1770647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_FLOAT_EQ, o, Float, "iF", "F", 1.0, 2.0);
1771647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Int, "iI", "I", 1, 2);
1772647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Long, "iJ", "J", 1, 2);
1773647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Short, "iS", "S", 1, 2);
1774885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes}
1775885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1776885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott HughesTEST_F(JniInternalTest, GetObjectField_SetObjectField) {
177700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Thread::Current()->TransitionFromSuspendedToRunnable();
177800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  LoadDex("AllFields");
177925c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom  runtime_->Start();
1780885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1781885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jclass c = env_->FindClass("AllFields");
17822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
1783885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jobject o = env_->AllocObject(c);
17842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
1785885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1786885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jstring s1 = env_->NewStringUTF("hello");
17872d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s1, nullptr);
1788885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jstring s2 = env_->NewStringUTF("world");
17892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s2, nullptr);
1790885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1791885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;");
17922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s_fid, nullptr);
1793885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;");
17942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(i_fid, nullptr);
1795885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1796885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  env_->SetStaticObjectField(c, s_fid, s1);
1797885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid)));
1798885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  env_->SetStaticObjectField(c, s_fid, s2);
1799885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid)));
1800885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1801885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  env_->SetObjectField(o, i_fid, s1);
1802885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid)));
1803885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  env_->SetObjectField(o, i_fid, s2);
1804885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid)));
1805885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes}
1806885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
18072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, NewLocalRef_nullptr) {
18082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->NewLocalRef(nullptr), nullptr);
180918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
181018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
181118c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, NewLocalRef) {
181218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
18132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
181418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewLocalRef(s);
18152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, nullptr);
18162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, s);
181718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
18182ced6a534157d5d963693346904389c19775d2daElliott Hughes  EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(o));
181918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
182018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
18212d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, DeleteLocalRef_nullptr) {
18222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->DeleteLocalRef(nullptr);
182318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
182418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
182518c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, DeleteLocalRef) {
1826369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  // This tests leads to warnings and errors in the log.
1827369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  ScopedLogSeverity sls(LogSeverity::FATAL);
1828369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe
182918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
18302d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
183118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteLocalRef(s);
183218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
18333f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes  // Currently, deleting an already-deleted reference is just a CheckJNI warning.
1834b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  {
183568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(false);
183668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    {
183768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      CheckJniAbortCatcher check_jni_abort_catcher;
183868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      env_->DeleteLocalRef(s);
183968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    }
1840b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    CheckJniAbortCatcher check_jni_abort_catcher;
184168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
1842b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    env_->DeleteLocalRef(s);
1843c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    std::string expected(StringPrintf("use of deleted local reference %p", s));
1844a9137c6bbdf4a1883f7b3f836c269eeb2ff619b2Elliott Hughes    check_jni_abort_catcher.Check(expected.c_str());
184568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1846b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
184718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
184818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  s = env_->NewStringUTF("");
18492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
185018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewLocalRef(s);
18512d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
185218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
185318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteLocalRef(s);
185418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteLocalRef(o);
185518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
185618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
1857aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott HughesTEST_F(JniInternalTest, PushLocalFrame_10395422) {
1858aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // The JNI specification is ambiguous about whether the given capacity is to be interpreted as a
1859aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // maximum or as a minimum, but it seems like it's supposed to be a minimum, and that's how
1860aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // Android historically treated it, and it's how the RI treats it. It's also the more useful
1861aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // interpretation!
1862aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  ASSERT_EQ(JNI_OK, env_->PushLocalFrame(0));
18632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->PopLocalFrame(nullptr);
1864aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes
1865369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  // The following two tests will print errors to the log.
1866369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  ScopedLogSeverity sls(LogSeverity::FATAL);
1867369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe
1868aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // Negative capacities are not allowed.
1869aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(-1));
1870aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes
1871aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // And it's okay to have an upper limit. Ours is currently 512.
1872aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(8192));
1873aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes}
1874aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes
18752ced6a534157d5d963693346904389c19775d2daElliott HughesTEST_F(JniInternalTest, PushLocalFrame_PopLocalFrame) {
1876369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  // This tests leads to errors in the log.
1877369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  ScopedLogSeverity sls(LogSeverity::FATAL);
1878369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe
18792ced6a534157d5d963693346904389c19775d2daElliott Hughes  jobject original = env_->NewStringUTF("");
18802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(original, nullptr);
18812ced6a534157d5d963693346904389c19775d2daElliott Hughes
18822ced6a534157d5d963693346904389c19775d2daElliott Hughes  jobject outer;
18832ced6a534157d5d963693346904389c19775d2daElliott Hughes  jobject inner1, inner2;
188400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(env_);
18852ced6a534157d5d963693346904389c19775d2daElliott Hughes  {
1886aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes    ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
18872ced6a534157d5d963693346904389c19775d2daElliott Hughes    outer = env_->NewLocalRef(original);
18882ced6a534157d5d963693346904389c19775d2daElliott Hughes
18892ced6a534157d5d963693346904389c19775d2daElliott Hughes    {
1890aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes      ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
18912ced6a534157d5d963693346904389c19775d2daElliott Hughes      inner1 = env_->NewLocalRef(outer);
18922ced6a534157d5d963693346904389c19775d2daElliott Hughes      inner2 = env_->NewStringUTF("survivor");
1893c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      EXPECT_NE(env_->PopLocalFrame(inner2), nullptr);
18942ced6a534157d5d963693346904389c19775d2daElliott Hughes    }
18952ced6a534157d5d963693346904389c19775d2daElliott Hughes
18962ced6a534157d5d963693346904389c19775d2daElliott Hughes    EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
18972ced6a534157d5d963693346904389c19775d2daElliott Hughes    EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(outer));
1898c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    {
1899c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      CheckJniAbortCatcher check_jni_abort_catcher;
1900c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
1901c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      check_jni_abort_catcher.Check("use of deleted local reference");
1902c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    }
19032ced6a534157d5d963693346904389c19775d2daElliott Hughes
19042ced6a534157d5d963693346904389c19775d2daElliott Hughes    // Our local reference for the survivor is invalid because the survivor
19052ced6a534157d5d963693346904389c19775d2daElliott Hughes    // gets a new local reference...
1906c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    {
1907c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      CheckJniAbortCatcher check_jni_abort_catcher;
1908c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
1909c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      check_jni_abort_catcher.Check("use of deleted local reference");
1910c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    }
19112ced6a534157d5d963693346904389c19775d2daElliott Hughes
1912c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    EXPECT_EQ(env_->PopLocalFrame(nullptr), nullptr);
19132ced6a534157d5d963693346904389c19775d2daElliott Hughes  }
19142ced6a534157d5d963693346904389c19775d2daElliott Hughes  EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
1915c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  CheckJniAbortCatcher check_jni_abort_catcher;
19162ced6a534157d5d963693346904389c19775d2daElliott Hughes  EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(outer));
1917c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  check_jni_abort_catcher.Check("use of deleted local reference");
19182ced6a534157d5d963693346904389c19775d2daElliott Hughes  EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
1919c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  check_jni_abort_catcher.Check("use of deleted local reference");
19202ced6a534157d5d963693346904389c19775d2daElliott Hughes  EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
1921c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  check_jni_abort_catcher.Check("use of deleted local reference");
19222ced6a534157d5d963693346904389c19775d2daElliott Hughes}
19232ced6a534157d5d963693346904389c19775d2daElliott Hughes
19242d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, NewGlobalRef_nullptr) {
19252d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->NewGlobalRef(nullptr), nullptr);
192618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
192718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
192818c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, NewGlobalRef) {
192918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
19302d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
193118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewGlobalRef(s);
19322d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, nullptr);
19332d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, s);
193418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
19352d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetObjectRefType(o), JNIGlobalRefType);
193618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
193718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
19382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, DeleteGlobalRef_nullptr) {
19392d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->DeleteGlobalRef(nullptr);
194018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
194118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
194218c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, DeleteGlobalRef) {
1943369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  // This tests leads to warnings and errors in the log.
1944369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  ScopedLogSeverity sls(LogSeverity::FATAL);
1945369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe
194618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
19472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
194818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
194918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewGlobalRef(s);
19502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
195118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteGlobalRef(o);
195218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
19533f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes  // Currently, deleting an already-deleted reference is just a CheckJNI warning.
1954b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  {
195568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(false);
195668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    {
195768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      CheckJniAbortCatcher check_jni_abort_catcher;
195868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      env_->DeleteGlobalRef(o);
195968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    }
1960b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    CheckJniAbortCatcher check_jni_abort_catcher;
196168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
1962b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    env_->DeleteGlobalRef(o);
1963c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    std::string expected(StringPrintf("use of deleted global reference %p", o));
1964a9137c6bbdf4a1883f7b3f836c269eeb2ff619b2Elliott Hughes    check_jni_abort_catcher.Check(expected.c_str());
196568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1966b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
196718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
196818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o1 = env_->NewGlobalRef(s);
19692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o1, nullptr);
197018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o2 = env_->NewGlobalRef(s);
19712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o2, nullptr);
197218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
197318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteGlobalRef(o1);
197418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteGlobalRef(o2);
197518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
197618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
19772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, NewWeakGlobalRef_nullptr) {
19782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->NewWeakGlobalRef(nullptr),   nullptr);
197918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
198018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
198118c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, NewWeakGlobalRef) {
198218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
19832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
198418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewWeakGlobalRef(s);
19852d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, nullptr);
19862d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, s);
198718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
19882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetObjectRefType(o), JNIWeakGlobalRefType);
198918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
199018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
19912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, DeleteWeakGlobalRef_nullptr) {
19922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->DeleteWeakGlobalRef(nullptr);
199318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
199418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
199518c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, DeleteWeakGlobalRef) {
1996369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  // This tests leads to warnings and errors in the log.
1997369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  ScopedLogSeverity sls(LogSeverity::FATAL);
1998369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe
199918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
20002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
200118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
200218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewWeakGlobalRef(s);
20032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
200418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteWeakGlobalRef(o);
200518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
20063f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes  // Currently, deleting an already-deleted reference is just a CheckJNI warning.
2007b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  {
200868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(false);
200968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    {
201068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      CheckJniAbortCatcher check_jni_abort_catcher;
201168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      env_->DeleteWeakGlobalRef(o);
201268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    }
2013b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    CheckJniAbortCatcher check_jni_abort_catcher;
201468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
2015b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    env_->DeleteWeakGlobalRef(o);
2016c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    std::string expected(StringPrintf("use of deleted weak global reference %p", o));
2017a9137c6bbdf4a1883f7b3f836c269eeb2ff619b2Elliott Hughes    check_jni_abort_catcher.Check(expected.c_str());
201868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
2019b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
202018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
202118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o1 = env_->NewWeakGlobalRef(s);
20222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o1, nullptr);
202318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o2 = env_->NewWeakGlobalRef(s);
20242d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o2, nullptr);
202518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
202618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteWeakGlobalRef(o1);
202718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteWeakGlobalRef(o2);
202818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
202918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
20303a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei ZavjalovTEST_F(JniInternalTest, ExceptionDescribe) {
20313a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov  // This checks how ExceptionDescribe handles call without exception.
20323a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov  env_->ExceptionClear();
20333a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov  env_->ExceptionDescribe();
20343a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov}
20353a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov
203637f7a40f6789bb287f287a9af00777af9d6428eeElliott HughesTEST_F(JniInternalTest, Throw) {
203737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass exception_class = env_->FindClass("java/lang/RuntimeException");
20382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(exception_class != nullptr);
203937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class));
20402d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(exception != nullptr);
204137f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
204237f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  EXPECT_EQ(JNI_OK, env_->Throw(exception));
204337f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  EXPECT_TRUE(env_->ExceptionCheck());
2044a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes  jthrowable thrown_exception = env_->ExceptionOccurred();
204537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  env_->ExceptionClear();
2046a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes  EXPECT_TRUE(env_->IsSameObject(exception, thrown_exception));
204737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
204868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  // Bad argument.
204968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
20502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(JNI_ERR, env_->Throw(nullptr));
205168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
205268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  CheckJniAbortCatcher check_jni_abort_catcher;
205368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(JNI_ERR, env_->Throw(nullptr));
205468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  check_jni_abort_catcher.Check("Throw received NULL jthrowable");
205568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
205668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers}
205737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
205868d8b42ddec39ec0174162d90d4abaa004d1983eIan RogersTEST_F(JniInternalTest, ThrowNew) {
205937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass exception_class = env_->FindClass("java/lang/RuntimeException");
20602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(exception_class != nullptr);
206137f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
20625cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  jthrowable thrown_exception;
20635cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes
206437f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
206537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  EXPECT_TRUE(env_->ExceptionCheck());
20665cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  thrown_exception = env_->ExceptionOccurred();
20675cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  env_->ExceptionClear();
20685cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
20695cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes
20702d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, nullptr));
20715cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  EXPECT_TRUE(env_->ExceptionCheck());
20725cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  thrown_exception = env_->ExceptionOccurred();
207337f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  env_->ExceptionClear();
2074a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
207568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
207668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  // Bad argument.
207768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
207868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  CheckJniAbortCatcher check_jni_abort_catcher;
207968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(JNI_ERR, env_->ThrowNew(nullptr, nullptr));
208068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  check_jni_abort_catcher.Check("c == null");
208168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
208268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(JNI_ERR, env_->ThrowNew(nullptr, nullptr));
208368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  check_jni_abort_catcher.Check("ThrowNew received NULL jclass");
208468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
208537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes}
208637f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
20871d99e4549309d05007d041d058b1878de88e9585Ian RogersTEST_F(JniInternalTest, NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) {
20881d99e4549309d05007d041d058b1878de88e9585Ian Rogers  // Start runtime.
20891d99e4549309d05007d041d058b1878de88e9585Ian Rogers  Thread* self = Thread::Current();
20901d99e4549309d05007d041d058b1878de88e9585Ian Rogers  self->TransitionFromSuspendedToRunnable();
20911d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.lang.Class");
20921d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.lang.Object");
20931d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.DirectByteBuffer");
20941fdb6963ddc8e82214926bfa732987483b86ab97Yi Kong  MakeExecutable(nullptr, "java.nio.Bits");
20951d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.MappedByteBuffer");
20961d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.ByteBuffer");
20971d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.Buffer");
20981d99e4549309d05007d041d058b1878de88e9585Ian Rogers  // TODO: we only load a dex file here as starting the runtime relies upon it.
20991d99e4549309d05007d041d058b1878de88e9585Ian Rogers  const char* class_name = "StaticLeafMethods";
21001d99e4549309d05007d041d058b1878de88e9585Ian Rogers  LoadDex(class_name);
21011d99e4549309d05007d041d058b1878de88e9585Ian Rogers  bool started = runtime_->Start();
21021d99e4549309d05007d041d058b1878de88e9585Ian Rogers  ASSERT_TRUE(started);
21031d99e4549309d05007d041d058b1878de88e9585Ian Rogers
2104b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jclass buffer_class = env_->FindClass("java/nio/Buffer");
21052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(buffer_class, nullptr);
2106b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
2107b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  char bytes[1024];
2108b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes));
21092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(buffer, nullptr);
2110b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class));
21112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_EQ(env_->GetDirectBufferAddress(buffer), bytes);
21121ee99352d85a07558688365dba70e9aa8f476c03Ian Rogers  ASSERT_EQ(env_->GetDirectBufferCapacity(buffer), static_cast<jlong>(sizeof(bytes)));
211345d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom
211445d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom  {
211545d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom    CheckJniAbortCatcher check_jni_abort_catcher;
211685a93364e5111dc56a73eed0130856e66cab0802Brian Carlstrom    env_->NewDirectByteBuffer(bytes, static_cast<jlong>(INT_MAX) + 1);
211745d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom    check_jni_abort_catcher.Check("in call to NewDirectByteBuffer");
211845d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom  }
2119b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes}
2120b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
21216d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian RogersTEST_F(JniInternalTest, MonitorEnterExit) {
2122369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  // This will print some error messages. Suppress.
2123369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  ScopedLogSeverity sls(LogSeverity::FATAL);
2124369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe
21252d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Create an object to torture.
21266d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  jclass object_class = env_->FindClass("java/lang/Object");
21272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(object_class, nullptr);
21286d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  jobject object = env_->AllocObject(object_class);
21292d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(object, nullptr);
21306d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
21316d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Expected class of exceptions
21326d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  jclass imse_class = env_->FindClass("java/lang/IllegalMonitorStateException");
21332d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(imse_class, nullptr);
21346d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
21356d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  jthrowable thrown_exception;
21366d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
21376d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Unlock of unowned monitor
21386d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->MonitorExit(object);
21396d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_TRUE(env_->ExceptionCheck());
21406d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  thrown_exception = env_->ExceptionOccurred();
21416d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->ExceptionClear();
21426d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
21436d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
21446d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Lock of unowned monitor
21456d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->MonitorEnter(object);
21466d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
21476d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Regular unlock
21486d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->MonitorExit(object);
21496d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
21506d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
21516d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Recursively lock a lot
21526d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  size_t max_recursive_lock = 1024;
21536d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  for (size_t i = 0; i < max_recursive_lock; i++) {
21546d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    env_->MonitorEnter(object);
21556d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    EXPECT_FALSE(env_->ExceptionCheck());
21566d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  }
21576d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Recursively unlock a lot
21586d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  for (size_t i = 0; i < max_recursive_lock; i++) {
21596d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    env_->MonitorExit(object);
21606d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    EXPECT_FALSE(env_->ExceptionCheck());
21616d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  }
21626d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
21636d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Unlock of unowned monitor
21646d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->MonitorExit(object);
21656d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_TRUE(env_->ExceptionCheck());
21666d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  thrown_exception = env_->ExceptionOccurred();
21676d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->ExceptionClear();
21686d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
2169a92853eb60fbce1fa6d3bbd6a6013fb514fdf5cbElliott Hughes
21702cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  // It's an error to call MonitorEnter or MonitorExit on null.
2171b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  {
2172b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    CheckJniAbortCatcher check_jni_abort_catcher;
21732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->MonitorEnter(nullptr);
2174b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    check_jni_abort_catcher.Check("in call to MonitorEnter");
21752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->MonitorExit(nullptr);
2176b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    check_jni_abort_catcher.Check("in call to MonitorExit");
2177b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
21786d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers}
21796d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
21805f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampevoid Java_MyClassNatives_foo_exit(JNIEnv* env, jobject thisObj) {
21815f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe  // Release the monitor on self. This should trigger an abort.
21825f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe  env->MonitorExit(thisObj);
21835f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe}
21845f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe
21855f4a09a54eed55de89e194780214a2acfd2cb431Andreas GampeTEST_F(JniInternalTest, MonitorExitLockedInDifferentCall) {
21865f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe  SetUpForTest(false, "foo", "()V", reinterpret_cast<void*>(&Java_MyClassNatives_foo_exit));
21875f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe  ASSERT_NE(jobj_, nullptr);
21885f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe
21895f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe  env_->MonitorEnter(jobj_);
21905f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe  EXPECT_FALSE(env_->ExceptionCheck());
21915f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe
21925f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe  CheckJniAbortCatcher check_jni_abort_catcher;
21935f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe  env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
21945f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe  check_jni_abort_catcher.Check("Unlocking monitor that wasn't locked here");
21955f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe}
21965f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe
21975f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampevoid Java_MyClassNatives_foo_enter_no_exit(JNIEnv* env, jobject thisObj) {
21985f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe  // Acquire but don't release the monitor on self. This should trigger an abort on return.
21995f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe  env->MonitorEnter(thisObj);
22005f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe}
22015f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe
22025f4a09a54eed55de89e194780214a2acfd2cb431Andreas GampeTEST_F(JniInternalTest, MonitorExitNotAllUnlocked) {
22035f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe  SetUpForTest(false,
22045f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe               "foo",
22055f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe               "()V",
22065f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe               reinterpret_cast<void*>(&Java_MyClassNatives_foo_enter_no_exit));
22075f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe  ASSERT_NE(jobj_, nullptr);
22085f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe
22095f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe  CheckJniAbortCatcher check_jni_abort_catcher;
22105f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe  env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
22115f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe  check_jni_abort_catcher.Check("Still holding a locked object on JNI end");
22125f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe}
22135f4a09a54eed55de89e194780214a2acfd2cb431Andreas Gampe
2214b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampestatic bool IsLocked(JNIEnv* env, jobject jobj) {
2215b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe  ScopedObjectAccess soa(env);
2216b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe  LockWord lock_word = soa.Decode<mirror::Object*>(jobj)->GetLockWord(true);
2217b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe  switch (lock_word.GetState()) {
2218b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe    case LockWord::kHashCode:
2219b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe    case LockWord::kUnlocked:
2220b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe      return false;
2221b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe    case LockWord::kThinLocked:
2222b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe      return true;
2223b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe    case LockWord::kFatLocked:
2224b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe      return lock_word.FatLockMonitor()->IsLocked();
2225b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe    default: {
2226b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe      LOG(FATAL) << "Invalid monitor state " << lock_word.GetState();
2227b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe      UNREACHABLE();
2228b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe    }
2229b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe  }
2230b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe}
2231b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe
2232b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas GampeTEST_F(JniInternalTest, DetachThreadUnlockJNIMonitors) {
2233b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe  // We need to lock an object, detach, reattach, and check the locks.
2234b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe  //
2235b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe  // As re-attaching will create a different thread, we need to use a global
2236b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe  // ref to keep the object around.
2237b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe
2238b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe  // Create an object to torture.
2239b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe  jobject global_ref;
2240b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe  {
2241b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe    jclass object_class = env_->FindClass("java/lang/Object");
2242b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe    ASSERT_NE(object_class, nullptr);
2243b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe    jobject object = env_->AllocObject(object_class);
2244b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe    ASSERT_NE(object, nullptr);
2245b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe    global_ref = env_->NewGlobalRef(object);
2246b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe  }
2247b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe
2248b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe  // Lock it.
2249b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe  env_->MonitorEnter(global_ref);
2250b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe  ASSERT_TRUE(IsLocked(env_, global_ref));
2251b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe
2252b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe  // Detach and re-attach.
2253b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe  jint detach_result = vm_->DetachCurrentThread();
2254b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe  ASSERT_EQ(detach_result, JNI_OK);
2255b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe  jint attach_result = vm_->AttachCurrentThread(&env_, nullptr);
2256b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe  ASSERT_EQ(attach_result, JNI_OK);
2257b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe
2258b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe  // Look at the global ref, check whether it's still locked.
2259b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe  ASSERT_FALSE(IsLocked(env_, global_ref));
2260b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe
2261b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe  // Delete the global ref.
2262b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe  env_->DeleteGlobalRef(global_ref);
2263b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe}
2264b8c4f033a29c16583ef9511f9a6e815caf0e64daAndreas Gampe
2265da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe// Test the offset computation of IndirectReferenceTable offsets. b/26071368.
2266da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas GampeTEST_F(JniInternalTest, IndirectReferenceTableOffsets) {
2267da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe  // The segment_state_ field is private, and we want to avoid friend declaration. So we'll check
2268da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe  // by modifying memory.
2269da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe  // The parameters don't really matter here.
2270da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe  IndirectReferenceTable irt(5, 5, IndirectRefKind::kGlobal, true);
2271da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe  uint32_t old_state = irt.GetSegmentState();
2272da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe
2273da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe  // Write some new state directly. We invert parts of old_state to ensure a new value.
2274da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe  uint32_t new_state = old_state ^ 0x07705005;
2275da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe  ASSERT_NE(old_state, new_state);
2276da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe
2277da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe  uint8_t* base = reinterpret_cast<uint8_t*>(&irt);
2278da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe  int32_t segment_state_offset =
2279da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe      IndirectReferenceTable::SegmentStateOffset(sizeof(void*)).Int32Value();
2280da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe  *reinterpret_cast<uint32_t*>(base + segment_state_offset) = new_state;
2281da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe
2282da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe  // Read and compare.
2283da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe  EXPECT_EQ(new_state, irt.GetSegmentState());
2284da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe}
2285da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe
2286da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe// Test the offset computation of JNIEnvExt offsets. b/26071368.
2287da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas GampeTEST_F(JniInternalTest, JNIEnvExtOffsets) {
2288da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe  EXPECT_EQ(OFFSETOF_MEMBER(JNIEnvExt, local_ref_cookie),
2289d59f3b1b7f5c1ab9f0731ff9dc60611e8d9a6edeVladimir Marko            JNIEnvExt::LocalRefCookieOffset(sizeof(void*)).Uint32Value());
2290da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe
2291d59f3b1b7f5c1ab9f0731ff9dc60611e8d9a6edeVladimir Marko  EXPECT_EQ(OFFSETOF_MEMBER(JNIEnvExt, self), JNIEnvExt::SelfOffset(sizeof(void*)).Uint32Value());
2292da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe
2293da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe  // segment_state_ is private in the IndirectReferenceTable. So this test isn't as good as we'd
2294da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe  // hope it to be.
2295d59f3b1b7f5c1ab9f0731ff9dc60611e8d9a6edeVladimir Marko  uint32_t segment_state_now =
2296da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe      OFFSETOF_MEMBER(JNIEnvExt, locals) +
2297d59f3b1b7f5c1ab9f0731ff9dc60611e8d9a6edeVladimir Marko      IndirectReferenceTable::SegmentStateOffset(sizeof(void*)).Uint32Value();
2298d59f3b1b7f5c1ab9f0731ff9dc60611e8d9a6edeVladimir Marko  uint32_t segment_state_computed = JNIEnvExt::SegmentStateOffset(sizeof(void*)).Uint32Value();
2299da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe  EXPECT_EQ(segment_state_now, segment_state_computed);
2300da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe}
2301da9b763abc712fd6d1e24170a194abfbe795b8cdAndreas Gampe
23020cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers}  // namespace art
2303