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
193d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier#include "art_method-inl.h"
20a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom#include "common_compiler_test.h"
2168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers#include "java_vm_ext.h"
2256890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih#include "mirror/string-inl.h"
23e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "scoped_thread_state_change.h"
24726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes#include "ScopedLocalRef.h"
250c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes
260c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughesnamespace art {
270c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes
28a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom// TODO: Convert to CommonRuntimeTest. Currently MakeExecutable is used.
29a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromclass JniInternalTest : public CommonCompilerTest {
30c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott Hughes protected:
31c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott Hughes  virtual void SetUp() {
32a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    CommonCompilerTest::SetUp();
335174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
34a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes    vm_ = Runtime::Current()->GetJavaVM();
35a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes
365174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes    // Turn on -verbose:jni for the JNI tests.
37797136386d6c66289ba1d12cbf5b2ac32646bb90Ian Rogers    // gLogVerbosity.jni = true;
385174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
392d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    vm_->AttachCurrentThread(&env_, nullptr);
40b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
41ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    ScopedLocalRef<jclass> aioobe(env_,
42ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                                  env_->FindClass("java/lang/ArrayIndexOutOfBoundsException"));
432d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK(aioobe.get() != nullptr);
44726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes    aioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(aioobe.get()));
45b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
46b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    ScopedLocalRef<jclass> ase(env_, env_->FindClass("java/lang/ArrayStoreException"));
472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK(ase.get() != nullptr);
48b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    ase_ = reinterpret_cast<jclass>(env_->NewGlobalRef(ase.get()));
49b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes
50ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    ScopedLocalRef<jclass> sioobe(env_,
51ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                                  env_->FindClass("java/lang/StringIndexOutOfBoundsException"));
522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK(sioobe.get() != nullptr);
53726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes    sioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(sioobe.get()));
54726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes  }
55726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes
562d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  void ExpectException(jclass exception_class) {
5768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ScopedObjectAccess soa(env_);
5868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_TRUE(env_->ExceptionCheck())
5968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        << PrettyDescriptor(soa.Decode<mirror::Class*>(exception_class));
602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jthrowable exception = env_->ExceptionOccurred();
612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_NE(nullptr, exception);
622d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->ExceptionClear();
632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class));
642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  }
652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
664d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom  void CleanUpJniEnv() {
672d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (aioobe_ != nullptr) {
684d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom      env_->DeleteGlobalRef(aioobe_);
692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      aioobe_ = nullptr;
704d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom    }
712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (ase_ != nullptr) {
724d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom      env_->DeleteGlobalRef(ase_);
732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      ase_ = nullptr;
744d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom    }
752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (sioobe_ != nullptr) {
764d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom      env_->DeleteGlobalRef(sioobe_);
772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      sioobe_ = nullptr;
784d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom    }
794d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom  }
804d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom
8153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers  virtual void TearDown() OVERRIDE {
824d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom    CleanUpJniEnv();
83a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    CommonCompilerTest::TearDown();
84c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott Hughes  }
85b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
861d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jclass GetPrimitiveClass(char descriptor) {
871d99e4549309d05007d041d058b1878de88e9585Ian Rogers    ScopedObjectAccess soa(env_);
881d99e4549309d05007d041d058b1878de88e9585Ian Rogers    mirror::Class* c = class_linker_->FindPrimitiveClass(descriptor);
891d99e4549309d05007d041d058b1878de88e9585Ian Rogers    CHECK(c != nullptr);
901d99e4549309d05007d041d058b1878de88e9585Ian Rogers    return soa.AddLocalReference<jclass>(c);
911d99e4549309d05007d041d058b1878de88e9585Ian Rogers  }
921d99e4549309d05007d041d058b1878de88e9585Ian Rogers
9368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void ExpectClassFound(const char* name) {
9468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_NE(env_->FindClass(name), nullptr) << name;
9568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_FALSE(env_->ExceptionCheck()) << name;
9668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
9768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
9868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void ExpectClassNotFound(const char* name, bool check_jni, const char* check_jni_msg,
9968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                           CheckJniAbortCatcher* abort_catcher) {
10068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->FindClass(name), nullptr) << name;
10168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    if (!check_jni || check_jni_msg == nullptr) {
10268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_TRUE(env_->ExceptionCheck()) << name;
10368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      env_->ExceptionClear();
10468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    } else {
10568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      abort_catcher->Check(check_jni_msg);
10668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    }
10768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
10868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
10968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void FindClassTest(bool check_jni) {
11068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
11168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher check_jni_abort_catcher;
11268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
11368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // Null argument is always an abort.
11468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->FindClass(nullptr);
11568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
11668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "name == null");
11768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
11868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // Reference types...
11968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassFound("java/lang/String");
12068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // ...for arrays too, where you must include "L;".
12168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassFound("[Ljava/lang/String;");
12268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // Primitive arrays are okay too, if the primitive type is valid.
12368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassFound("[C");
12468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
12568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // But primitive types aren't allowed...
12668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassNotFound("C", check_jni, nullptr, &check_jni_abort_catcher);
12768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassNotFound("V", check_jni, nullptr, &check_jni_abort_catcher);
12868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassNotFound("K", check_jni, nullptr, &check_jni_abort_catcher);
12968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
13068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    if (check_jni) {
13168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      // Check JNI will reject invalid class names as aborts but without pending exceptions.
13268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_EQ(env_->FindClass("java.lang.String"), nullptr);
13368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_FALSE(env_->ExceptionCheck());
13468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      check_jni_abort_catcher.Check("illegal class name 'java.lang.String'");
13568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
13668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_EQ(env_->FindClass("[Ljava.lang.String;"), nullptr);
13768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_FALSE(env_->ExceptionCheck());
13868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      check_jni_abort_catcher.Check("illegal class name '[Ljava.lang.String;'");
13968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    } else {
14068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      // Without check JNI we're tolerant and replace '.' with '/'.
14168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      ExpectClassFound("java.lang.String");
14268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      ExpectClassFound("[Ljava.lang.String;");
14368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    }
14468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
14568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassNotFound("Ljava.lang.String;", check_jni, "illegal class name 'Ljava.lang.String;'",
14668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                        &check_jni_abort_catcher);
14768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassNotFound("[java.lang.String", check_jni, "illegal class name '[java.lang.String'",
14868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                        &check_jni_abort_catcher);
14968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
15068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // You can't include the "L;" in a JNI class descriptor.
15168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassNotFound("Ljava/lang/String;", check_jni, "illegal class name 'Ljava/lang/String;'",
15268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                        &check_jni_abort_catcher);
15368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
15468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // But you must include it for an array of any reference type.
15568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassNotFound("[java/lang/String", check_jni, "illegal class name '[java/lang/String'",
15668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                        &check_jni_abort_catcher);
15768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
15868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassNotFound("[K", check_jni, "illegal class name '[K'", &check_jni_abort_catcher);
15968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
16068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // Void arrays aren't allowed.
16168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ExpectClassNotFound("[V", check_jni, "illegal class name '[V'", &check_jni_abort_catcher);
16268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
16368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
16468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
16568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
16668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void GetFieldIdBadArgumentTest(bool check_jni) {
16768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
16868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher check_jni_abort_catcher;
16968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
17068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass c = env_->FindClass("java/lang/String");
17168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_NE(c, nullptr);
17268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
17368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jfieldID fid = env_->GetFieldID(nullptr, "count", "I");
17468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, fid);
17568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "GetFieldID received NULL jclass"
17668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "java_class == null");
17768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    fid = env_->GetFieldID(c, nullptr, "I");
17868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, fid);
17968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
18068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "name == null");
18168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    fid = env_->GetFieldID(c, "count", nullptr);
18268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, fid);
18368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
18468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "sig == null");
18568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
18668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
18768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
18868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
18968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void GetStaticFieldIdBadArgumentTest(bool check_jni) {
19068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
19168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher check_jni_abort_catcher;
19268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
19368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass c = env_->FindClass("java/lang/String");
19468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_NE(c, nullptr);
19568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
19668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jfieldID fid = env_->GetStaticFieldID(nullptr, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
19768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, fid);
19868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "GetStaticFieldID received NULL jclass"
19968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "java_class == null");
20068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    fid = env_->GetStaticFieldID(c, nullptr, "Ljava/util/Comparator;");
20168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, fid);
20268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
20368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "name == null");
20468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", nullptr);
20568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, fid);
20668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
20768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "sig == null");
20868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
20968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
21068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
21168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
21268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void GetMethodIdBadArgumentTest(bool check_jni) {
21368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
21468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher check_jni_abort_catcher;
21568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
21668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jmethodID method = env_->GetMethodID(nullptr, "<init>", "(Ljava/lang/String;)V");
21768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, method);
21868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "GetMethodID received NULL jclass"
21968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "java_class == null");
22068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
22168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_TRUE(jlnsme != nullptr);
22268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    method = env_->GetMethodID(jlnsme, nullptr, "(Ljava/lang/String;)V");
22368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, method);
22468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
22568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "name == null");
22668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    method = env_->GetMethodID(jlnsme, "<init>", nullptr);
22768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, method);
22868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
22968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "sig == null");
23068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
23168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
23268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
23368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
23468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void GetStaticMethodIdBadArgumentTest(bool check_jni) {
23568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
23668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher check_jni_abort_catcher;
23768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
23868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jmethodID method = env_->GetStaticMethodID(nullptr, "valueOf", "(I)Ljava/lang/String;");
23968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, method);
24068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "GetStaticMethodID received NULL jclass"
24168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "java_class == null");
24268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass jlstring = env_->FindClass("java/lang/String");
24368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    method = env_->GetStaticMethodID(jlstring, nullptr, "(I)Ljava/lang/String;");
24468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, method);
24568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
24668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "name == null");
24768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    method = env_->GetStaticMethodID(jlstring, "valueOf", nullptr);
24868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(nullptr, method);
24968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
25068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "sig == null");
25168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
25268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
25368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
25468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
25568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void GetFromReflectedField_ToReflectedFieldBadArgumentTest(bool check_jni) {
25668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
25768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher check_jni_abort_catcher;
25868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
25968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass c = env_->FindClass("java/lang/String");
26068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_NE(c, nullptr);
26168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jfieldID fid = env_->GetFieldID(c, "count", "I");
26268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_NE(fid, nullptr);
26368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
26468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // Check class argument for null argument, not checked in non-check JNI.
26568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jobject field = env_->ToReflectedField(nullptr, fid, JNI_FALSE);
26668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    if (check_jni) {
26768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_EQ(field, nullptr);
26868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      check_jni_abort_catcher.Check("ToReflectedField received NULL jclass");
26968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    } else {
27068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_NE(field, nullptr);
27168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    }
27268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
27368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    field = env_->ToReflectedField(c, nullptr, JNI_FALSE);
27468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(field, nullptr);
27568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "jfieldID was NULL"
27668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "fid == null");
27768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
27868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    fid = env_->FromReflectedField(nullptr);
27968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_EQ(fid, nullptr);
28068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "expected non-null java.lang.reflect.Field"
28168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "jlr_field == null");
28268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
28368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
28468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
28568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
28668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void GetFromReflectedMethod_ToReflectedMethodBadArgumentTest(bool check_jni) {
28768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
28868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher check_jni_abort_catcher;
28968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
29068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass c = env_->FindClass("java/lang/String");
29168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_NE(c, nullptr);
29268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jmethodID mid = env_->GetMethodID(c, "<init>", "()V");
29368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_NE(mid, nullptr);
29468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
29568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // Check class argument for null argument, not checked in non-check JNI.
29668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jobject method = env_->ToReflectedMethod(nullptr, mid, JNI_FALSE);
29768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    if (check_jni) {
29868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_EQ(method, nullptr);
29968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      check_jni_abort_catcher.Check("ToReflectedMethod received NULL jclass");
30068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    } else {
30168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_NE(method, nullptr);
30268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    }
30368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
30468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    method = env_->ToReflectedMethod(c, nullptr, JNI_FALSE);
30568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(method, nullptr);
30668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "jmethodID was NULL"
30768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                            : "mid == null");
30868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    mid = env_->FromReflectedMethod(method);
30968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_EQ(mid, nullptr);
31068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check(check_jni ? "expected non-null method" : "jlr_method == null");
31168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
31268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
31368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
31468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
31568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void RegisterAndUnregisterNativesBadArguments(bool check_jni,
31668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                                CheckJniAbortCatcher* check_jni_abort_catcher) {
31768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
31868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // Passing a class of null is a failure.
31968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    {
32068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      JNINativeMethod methods[] = { };
32168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      EXPECT_EQ(env_->RegisterNatives(nullptr, methods, 0), JNI_ERR);
32268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      check_jni_abort_catcher->Check(check_jni ? "RegisterNatives received NULL jclass"
32368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                               : "java_class == null");
32468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    }
32568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
32668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // Passing methods as null is a failure.
32768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass jlobject = env_->FindClass("java/lang/Object");
32868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->RegisterNatives(jlobject, nullptr, 1), JNI_ERR);
32968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher->Check("methods == null");
33068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
33168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    // Unregisters null is a failure.
33268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->UnregisterNatives(nullptr), JNI_ERR);
33368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher->Check(check_jni ? "UnregisterNatives received NULL jclass"
33468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                             : "java_class == null");
33568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
33668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
33768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
33868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
33968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
34068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void GetPrimitiveArrayElementsOfWrongType(bool check_jni) {
34168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
34268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher jni_abort_catcher;
34368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
34468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jbooleanArray array = env_->NewBooleanArray(10);
34568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jboolean is_copy;
34668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetByteArrayElements(reinterpret_cast<jbyteArray>(array), &is_copy), nullptr);
34768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
34868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected byte[]"
34968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get byte primitive array elements with an object of type boolean[]");
35068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetShortArrayElements(reinterpret_cast<jshortArray>(array), &is_copy), nullptr);
35168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
35268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected short[]"
35368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get short primitive array elements with an object of type boolean[]");
35468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetCharArrayElements(reinterpret_cast<jcharArray>(array), &is_copy), nullptr);
35568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
35668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected char[]"
35768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get char primitive array elements with an object of type boolean[]");
35868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetIntArrayElements(reinterpret_cast<jintArray>(array), &is_copy), nullptr);
35968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
36068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected int[]"
36168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get int primitive array elements with an object of type boolean[]");
36268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetLongArrayElements(reinterpret_cast<jlongArray>(array), &is_copy), nullptr);
36368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
36468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected long[]"
36568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get long primitive array elements with an object of type boolean[]");
36668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetFloatArrayElements(reinterpret_cast<jfloatArray>(array), &is_copy), nullptr);
36768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
36868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected float[]"
36968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get float primitive array elements with an object of type boolean[]");
37068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetDoubleArrayElements(reinterpret_cast<jdoubleArray>(array), &is_copy), nullptr);
37168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
37268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected double[]"
37368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get double primitive array elements with an object of type boolean[]");
37468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jbyteArray array2 = env_->NewByteArray(10);
37568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetBooleanArrayElements(reinterpret_cast<jbooleanArray>(array2), &is_copy),
37668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers              nullptr);
37768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
37868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type byte[] expected boolean[]"
37968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get boolean primitive array elements with an object of type byte[]");
38068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jobject object = env_->NewStringUTF("Test String");
38168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetBooleanArrayElements(reinterpret_cast<jbooleanArray>(object), &is_copy),
38268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers              nullptr);
38368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
38468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "jarray argument has non-array type: java.lang.String"
38568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        : "attempt to get boolean primitive array elements with an object of type java.lang.String");
38668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
38768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
38868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
38968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
39068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void ReleasePrimitiveArrayElementsOfWrongType(bool check_jni) {
39168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
39268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher jni_abort_catcher;
393dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers    {
394dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jbooleanArray array = env_->NewBooleanArray(10);
395dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      ASSERT_TRUE(array != nullptr);
396dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jboolean is_copy;
397dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jboolean* elements = env_->GetBooleanArrayElements(array, &is_copy);
398dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      ASSERT_TRUE(elements != nullptr);
399dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      env_->ReleaseByteArrayElements(reinterpret_cast<jbyteArray>(array),
400dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers                                     reinterpret_cast<jbyte*>(elements), 0);
401dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jni_abort_catcher.Check(
402dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers          check_jni ? "incompatible array type boolean[] expected byte[]"
403dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers              : "attempt to release byte primitive array elements with an object of type boolean[]");
404dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      env_->ReleaseShortArrayElements(reinterpret_cast<jshortArray>(array),
405dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers                                      reinterpret_cast<jshort*>(elements), 0);
406dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jni_abort_catcher.Check(
407dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers          check_jni ? "incompatible array type boolean[] expected short[]"
408dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers              : "attempt to release short primitive array elements with an object of type boolean[]");
409dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      env_->ReleaseCharArrayElements(reinterpret_cast<jcharArray>(array),
410dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers                                     reinterpret_cast<jchar*>(elements), 0);
411dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jni_abort_catcher.Check(
412dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers          check_jni ? "incompatible array type boolean[] expected char[]"
413dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers              : "attempt to release char primitive array elements with an object of type boolean[]");
414dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      env_->ReleaseIntArrayElements(reinterpret_cast<jintArray>(array),
415dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers                                    reinterpret_cast<jint*>(elements), 0);
416dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jni_abort_catcher.Check(
417dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers          check_jni ? "incompatible array type boolean[] expected int[]"
418dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers              : "attempt to release int primitive array elements with an object of type boolean[]");
419dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      env_->ReleaseLongArrayElements(reinterpret_cast<jlongArray>(array),
420dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers                                     reinterpret_cast<jlong*>(elements), 0);
421dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jni_abort_catcher.Check(
422dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers          check_jni ? "incompatible array type boolean[] expected long[]"
423dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers              : "attempt to release long primitive array elements with an object of type boolean[]");
424dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      env_->ReleaseFloatArrayElements(reinterpret_cast<jfloatArray>(array),
425dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers                                      reinterpret_cast<jfloat*>(elements), 0);
426dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jni_abort_catcher.Check(
427dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers          check_jni ? "incompatible array type boolean[] expected float[]"
428dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers              : "attempt to release float primitive array elements with an object of type boolean[]");
429dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      env_->ReleaseDoubleArrayElements(reinterpret_cast<jdoubleArray>(array),
430dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers                                       reinterpret_cast<jdouble*>(elements), 0);
431dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jni_abort_catcher.Check(
432dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers          check_jni ? "incompatible array type boolean[] expected double[]"
433dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers              : "attempt to release double primitive array elements with an object of type boolean[]");
434dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers
435dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      // Don't leak the elements array.
436dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      env_->ReleaseBooleanArrayElements(array, elements, 0);
437dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers    }
438dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers    {
439dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jbyteArray array = env_->NewByteArray(10);
440dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jboolean is_copy;
441dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jbyte* elements = env_->GetByteArrayElements(array, &is_copy);
442dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers
443dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      env_->ReleaseBooleanArrayElements(reinterpret_cast<jbooleanArray>(array),
444dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers                                        reinterpret_cast<jboolean*>(elements), 0);
445dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jni_abort_catcher.Check(
446dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers          check_jni ? "incompatible array type byte[] expected boolean[]"
447dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers              : "attempt to release boolean primitive array elements with an object of type byte[]");
448dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jobject object = env_->NewStringUTF("Test String");
449dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      env_->ReleaseBooleanArrayElements(reinterpret_cast<jbooleanArray>(object),
450dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers                                        reinterpret_cast<jboolean*>(elements), 0);
451dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      jni_abort_catcher.Check(
452dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers          check_jni ? "jarray argument has non-array type: java.lang.String"
453dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers              : "attempt to release boolean primitive array elements with an object of type "
45468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers              "java.lang.String");
45568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
456dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      // Don't leak the elements array.
457dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers      env_->ReleaseByteArrayElements(array, elements, 0);
458dd11d2a89a9150122a1cb55fba2b003c6d389fa0Ian Rogers    }
45968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
46068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
46168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
46268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void GetReleasePrimitiveArrayCriticalOfWrongType(bool check_jni) {
46368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
46468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher jni_abort_catcher;
46568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
46668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jobject object = env_->NewStringUTF("Test String");
46768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jboolean is_copy;
46868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    void* elements = env_->GetPrimitiveArrayCritical(reinterpret_cast<jarray>(object), &is_copy);
46968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String"
47068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        : "expected primitive array, given java.lang.String");
47168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->ReleasePrimitiveArrayCritical(reinterpret_cast<jarray>(object), elements, 0);
47268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String"
47368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        : "expected primitive array, given java.lang.String");
47468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
47568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
47668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
47768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
47868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void GetPrimitiveArrayRegionElementsOfWrongType(bool check_jni) {
47968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
48068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher jni_abort_catcher;
48168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    constexpr size_t kLength = 10;
48268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jbooleanArray array = env_->NewBooleanArray(kLength);
48368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_TRUE(array != nullptr);
48468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jboolean elements[kLength];
48568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetByteArrayRegion(reinterpret_cast<jbyteArray>(array), 0, kLength,
48668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                             reinterpret_cast<jbyte*>(elements));
48768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
48868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected byte[]"
48968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get region of byte primitive array elements with an object of type boolean[]");
49068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetShortArrayRegion(reinterpret_cast<jshortArray>(array), 0, kLength,
49168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                              reinterpret_cast<jshort*>(elements));
49268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
49368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected short[]"
49468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get region of short primitive array elements with an object of type boolean[]");
49568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetCharArrayRegion(reinterpret_cast<jcharArray>(array), 0, kLength,
49668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                             reinterpret_cast<jchar*>(elements));
49768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
49868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected char[]"
49968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get region of char primitive array elements with an object of type boolean[]");
50068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetIntArrayRegion(reinterpret_cast<jintArray>(array), 0, kLength,
50168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                            reinterpret_cast<jint*>(elements));
50268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
50368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected int[]"
50468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get region of int primitive array elements with an object of type boolean[]");
50568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetLongArrayRegion(reinterpret_cast<jlongArray>(array), 0, kLength,
50668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                             reinterpret_cast<jlong*>(elements));
50768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
50868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected long[]"
50968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get region of long primitive array elements with an object of type boolean[]");
51068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetFloatArrayRegion(reinterpret_cast<jfloatArray>(array), 0, kLength,
51168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                              reinterpret_cast<jfloat*>(elements));
51268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
51368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected float[]"
51468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get region of float primitive array elements with an object of type boolean[]");
51568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetDoubleArrayRegion(reinterpret_cast<jdoubleArray>(array), 0, kLength,
51668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                               reinterpret_cast<jdouble*>(elements));
51768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
51868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected double[]"
51968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get region of double primitive array elements with an object of type boolean[]");
52068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jbyteArray array2 = env_->NewByteArray(10);
52168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(array2), 0, kLength,
52268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                reinterpret_cast<jboolean*>(elements));
52368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
52468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type byte[] expected boolean[]"
52568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to get region of boolean primitive array elements with an object of type byte[]");
52668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jobject object = env_->NewStringUTF("Test String");
52768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(object), 0, kLength,
52868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                reinterpret_cast<jboolean*>(elements));
52968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String"
53068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        : "attempt to get region of boolean primitive array elements with an object of type "
53168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers          "java.lang.String");
53268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
53368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
53468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
53568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
53668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void SetPrimitiveArrayRegionElementsOfWrongType(bool check_jni) {
53768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
53868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher jni_abort_catcher;
53968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    constexpr size_t kLength = 10;
54068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jbooleanArray array = env_->NewBooleanArray(kLength);
54168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_TRUE(array != nullptr);
54268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jboolean elements[kLength];
54368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetByteArrayRegion(reinterpret_cast<jbyteArray>(array), 0, kLength,
54468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                             reinterpret_cast<jbyte*>(elements));
54568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
54668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected byte[]"
54768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to set region of byte primitive array elements with an object of type boolean[]");
54868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetShortArrayRegion(reinterpret_cast<jshortArray>(array), 0, kLength,
54968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                              reinterpret_cast<jshort*>(elements));
55068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
55168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected short[]"
55268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to set region of short primitive array elements with an object of type boolean[]");
55368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetCharArrayRegion(reinterpret_cast<jcharArray>(array), 0, kLength,
55468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                             reinterpret_cast<jchar*>(elements));
55568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
55668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected char[]"
55768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to set region of char primitive array elements with an object of type boolean[]");
55868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetIntArrayRegion(reinterpret_cast<jintArray>(array), 0, kLength,
55968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                            reinterpret_cast<jint*>(elements));
56068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
56168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected int[]"
56268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to set region of int primitive array elements with an object of type boolean[]");
56368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetLongArrayRegion(reinterpret_cast<jlongArray>(array), 0, kLength,
56468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                             reinterpret_cast<jlong*>(elements));
56568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
56668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected long[]"
56768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to set region of long primitive array elements with an object of type boolean[]");
56868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetFloatArrayRegion(reinterpret_cast<jfloatArray>(array), 0, kLength,
56968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                              reinterpret_cast<jfloat*>(elements));
57068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
57168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected float[]"
57268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to set region of float primitive array elements with an object of type boolean[]");
57368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetDoubleArrayRegion(reinterpret_cast<jdoubleArray>(array), 0, kLength,
57468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                               reinterpret_cast<jdouble*>(elements));
57568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
57668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type boolean[] expected double[]"
57768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to set region of double primitive array elements with an object of type boolean[]");
57868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jbyteArray array2 = env_->NewByteArray(10);
57968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(array2), 0, kLength,
58068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                reinterpret_cast<jboolean*>(elements));
58168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(
58268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        check_jni ? "incompatible array type byte[] expected boolean[]"
58368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers            : "attempt to set region of boolean primitive array elements with an object of type byte[]");
58468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jobject object = env_->NewStringUTF("Test String");
58568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(object), 0, kLength,
58668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                reinterpret_cast<jboolean*>(elements));
58768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String"
58868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        : "attempt to set region of boolean primitive array elements with an object of type "
58968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers          "java.lang.String");
59068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
59168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
59268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
59368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  void NewObjectArrayBadArguments(bool check_jni) {
59468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
59568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher jni_abort_catcher;
59668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
59768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass element_class = env_->FindClass("java/lang/String");
59868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ASSERT_NE(element_class, nullptr);
59968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
60068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->NewObjectArray(-1, element_class, nullptr);
60168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(check_jni ? "negative jsize: -1" : "negative array length: -1");
60268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
60368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->NewObjectArray(std::numeric_limits<jint>::min(), element_class, nullptr);
60468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(check_jni ? "negative jsize: -2147483648"
60568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        : "negative array length: -2147483648");
60668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
60768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
60868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
60968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
610a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes  JavaVMExt* vm_;
6114d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom  JNIEnv* env_;
612814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  jclass aioobe_;
613b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  jclass ase_;
614b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jclass sioobe_;
6150c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes};
6160c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes
617885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott HughesTEST_F(JniInternalTest, AllocObject) {
618885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jclass c = env_->FindClass("java/lang/String");
6192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
620885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jobject o = env_->AllocObject(c);
6212d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
622885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
623885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  // We have an instance of the class we asked for...
624885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsInstanceOf(o, c));
625885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  // ...whose fields haven't been initialized because
626885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  // we didn't call a constructor.
627885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "count", "I")));
628885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes}
629885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
630c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott HughesTEST_F(JniInternalTest, GetVersion) {
631c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott Hughes  ASSERT_EQ(JNI_VERSION_1_6, env_->GetVersion());
632c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott Hughes}
633c7ac37f0b8b64cfb53d8b9cc8dddbb34be3dd5eeElliott Hughes
6340c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott HughesTEST_F(JniInternalTest, FindClass) {
635369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  // This tests leads to warnings in the log.
636369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  ScopedLogSeverity sls(LogSeverity::ERROR);
637369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe
63868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  FindClassTest(false);
63968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  FindClassTest(true);
6400c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes}
6410c9cd5692fbbc5d92fcdc1ef41ef881a492b00ceElliott Hughes
642cdf53120cd5a73cbedc1654e22542848468c0d2fElliott HughesTEST_F(JniInternalTest, GetFieldID) {
643cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
6442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(jlnsfe, nullptr);
645cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass c = env_->FindClass("java/lang/String");
6462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
647cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
648cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Wrong type.
649cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jfieldID fid = env_->GetFieldID(c, "count", "J");
6502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
6512d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
652cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
653b17d08b6ef0d36038e408dd79960293bb62ec1d9Ian Rogers  // Wrong type where type doesn't exist.
654b17d08b6ef0d36038e408dd79960293bb62ec1d9Ian Rogers  fid = env_->GetFieldID(c, "count", "Lrod/jane/freddy;");
6552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
6562d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
657b17d08b6ef0d36038e408dd79960293bb62ec1d9Ian Rogers
658cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Wrong name.
659cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetFieldID(c, "Count", "I");
6602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
6612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
662cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
663cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Good declared field lookup.
664cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetFieldID(c, "count", "I");
6652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(nullptr, fid);
666cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  EXPECT_FALSE(env_->ExceptionCheck());
667cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
668cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Good superclass field lookup.
669cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  c = env_->FindClass("java/lang/StringBuilder");
670cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetFieldID(c, "count", "I");
6712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(nullptr, fid);
6722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(fid, nullptr);
673cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  EXPECT_FALSE(env_->ExceptionCheck());
674cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
675cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Not instance.
676cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
6772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
6782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
6792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
6802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Bad arguments.
68168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetFieldIdBadArgumentTest(false);
68268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetFieldIdBadArgumentTest(true);
683cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes}
684cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
685cdf53120cd5a73cbedc1654e22542848468c0d2fElliott HughesTEST_F(JniInternalTest, GetStaticFieldID) {
686cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
6872d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(jlnsfe, nullptr);
688cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass c = env_->FindClass("java/lang/String");
6892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
690cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
691cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Wrong type.
692cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J");
6932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
6942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
695cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
696b17d08b6ef0d36038e408dd79960293bb62ec1d9Ian Rogers  // Wrong type where type doesn't exist.
697b17d08b6ef0d36038e408dd79960293bb62ec1d9Ian Rogers  fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Lrod/jane/freddy;");
6982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
6992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
700b17d08b6ef0d36038e408dd79960293bb62ec1d9Ian Rogers
701cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Wrong name.
702cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
7032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
7042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
705cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
706cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Good declared field lookup.
707cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
7082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(nullptr, fid);
7092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(fid, nullptr);
710cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  EXPECT_FALSE(env_->ExceptionCheck());
711cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
712cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Not static.
713cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  fid = env_->GetStaticFieldID(c, "count", "I");
7142d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, fid);
7152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsfe);
7162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
7172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Bad arguments.
71868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetStaticFieldIdBadArgumentTest(false);
71968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetStaticFieldIdBadArgumentTest(true);
720cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes}
721cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
7224dd71f1538a8d788c56c77378a59ce32afa519d7Ian RogersTEST_F(JniInternalTest, GetMethodID) {
7234dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlobject = env_->FindClass("java/lang/Object");
7244dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlstring = env_->FindClass("java/lang/String");
7254dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
726004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  jclass jncrbc = env_->FindClass("java/nio/channels/ReadableByteChannel");
7274dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
728004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  // Sanity check that no exceptions are pending.
729cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  ASSERT_FALSE(env_->ExceptionCheck());
7304dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
7314dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
732004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  // a pending exception.
7334dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jmethodID method = env_->GetMethodID(jlobject, "foo", "()V");
7342d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, method);
7352d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsme);
7364dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
737004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  // Check that java.lang.Object.equals() does exist.
7384dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
7392d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(nullptr, method);
7404dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
7414dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
7424dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // Check that GetMethodID for java.lang.String.valueOf(int) fails as the
743004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  // method is static.
7444dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
7452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, method);
7462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsme);
747ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom
748004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  // Check that GetMethodID for java.lang.NoSuchMethodError.<init>(String) finds the constructor.
749ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  method = env_->GetMethodID(jlnsme, "<init>", "(Ljava/lang/String;)V");
7502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(nullptr, method);
751ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_FALSE(env_->ExceptionCheck());
7522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
753004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  // Check that GetMethodID can find a interface method inherited from another interface.
754004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  method = env_->GetMethodID(jncrbc, "close", "()V");
755004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  EXPECT_NE(nullptr, method);
756004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  EXPECT_FALSE(env_->ExceptionCheck());
757004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom
7582d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Bad arguments.
75968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetMethodIdBadArgumentTest(false);
76068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetMethodIdBadArgumentTest(true);
7614dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers}
7624dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
763a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu ChartierTEST_F(JniInternalTest, CallVoidMethodNullReceiver) {
764a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  jclass jlobject = env_->FindClass("java/lang/Object");
765a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  jmethodID method;
766a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier
767a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  // Check that GetMethodID for java.lang.NoSuchMethodError.<init>(String) finds the constructor.
768a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  method = env_->GetMethodID(jlobject, "<init>", "()V");
769a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  EXPECT_NE(nullptr, method);
770a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  EXPECT_FALSE(env_->ExceptionCheck());
771a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier
772a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  // Null object to CallVoidMethod.
773a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  CheckJniAbortCatcher check_jni_abort_catcher;
774a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  env_->CallVoidMethod(nullptr, method);
775a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier  check_jni_abort_catcher.Check("null");
776a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier}
777a1e78fa763c9883af1c01a6c10fac5f5aa2f9659Mathieu Chartier
7784dd71f1538a8d788c56c77378a59ce32afa519d7Ian RogersTEST_F(JniInternalTest, GetStaticMethodID) {
7794dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlobject = env_->FindClass("java/lang/Object");
7804dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
7814dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
7824dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // Sanity check that no exceptions are pending
783cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  ASSERT_FALSE(env_->ExceptionCheck());
7844dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
7854dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
7864dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // a pending exception
7874dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V");
7882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, method);
7892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsme);
7904dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
7914dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as
7924dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // the method is not static
7934dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
7942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, method);
7952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(jlnsme);
7964dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
7974dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  // Check that java.lang.String.valueOf(int) does exist
7984dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlstring = env_->FindClass("java/lang/String");
7992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  method = env_->GetStaticMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
8002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(nullptr, method);
8014dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
8022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
8032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Bad arguments.
80468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetStaticMethodIdBadArgumentTest(false);
80568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetStaticMethodIdBadArgumentTest(true);
8064dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers}
8074dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
808cdf53120cd5a73cbedc1654e22542848468c0d2fElliott HughesTEST_F(JniInternalTest, FromReflectedField_ToReflectedField) {
809cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass jlrField = env_->FindClass("java/lang/reflect/Field");
810cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass c = env_->FindClass("java/lang/String");
8112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
812cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jfieldID fid = env_->GetFieldID(c, "count", "I");
8132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(fid, nullptr);
814cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Turn the fid into a java.lang.reflect.Field...
815cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jobject field = env_->ToReflectedField(c, fid, JNI_FALSE);
81678959466de4e53d768d135ae301473cc7f4def99Mathieu Chartier  for (size_t i = 0; i <= kLocalsMax; ++i) {
81741da59665556e8dd5601178185c68d48d645500bMathieu Chartier    // Regression test for b/18396311, ToReflectedField leaking local refs causing a local
81841da59665556e8dd5601178185c68d48d645500bMathieu Chartier    // reference table overflows with 512 references to ArtField
81941da59665556e8dd5601178185c68d48d645500bMathieu Chartier    env_->DeleteLocalRef(env_->ToReflectedField(c, fid, JNI_FALSE));
82041da59665556e8dd5601178185c68d48d645500bMathieu Chartier  }
8212d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
822cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  ASSERT_TRUE(env_->IsInstanceOf(field, jlrField));
823cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // ...and back again.
824cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jfieldID fid2 = env_->FromReflectedField(field);
8252d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(fid2, nullptr);
826ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  // Make sure we can actually use it.
827ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  jstring s = env_->NewStringUTF("poop");
828ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  ASSERT_EQ(4, env_->GetIntField(s, fid2));
8292d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
8302d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Bad arguments.
83168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetFromReflectedField_ToReflectedFieldBadArgumentTest(false);
83268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetFromReflectedField_ToReflectedFieldBadArgumentTest(true);
833cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes}
834cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
835cdf53120cd5a73cbedc1654e22542848468c0d2fElliott HughesTEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
836cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass jlrMethod = env_->FindClass("java/lang/reflect/Method");
837d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(jlrMethod, nullptr);
838d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  jclass jlrConstructor = env_->FindClass("java/lang/reflect/Constructor");
839d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(jlrConstructor, nullptr);
840cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jclass c = env_->FindClass("java/lang/String");
8412d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
842d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz
843d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  jmethodID mid = env_->GetMethodID(c, "<init>", "()V");
8442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(mid, nullptr);
845d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  // Turn the mid into a java.lang.reflect.Constructor...
846cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
84778959466de4e53d768d135ae301473cc7f4def99Mathieu Chartier  for (size_t i = 0; i <= kLocalsMax; ++i) {
84841da59665556e8dd5601178185c68d48d645500bMathieu Chartier    // Regression test for b/18396311, ToReflectedMethod leaking local refs causing a local
84941da59665556e8dd5601178185c68d48d645500bMathieu Chartier    // reference table overflows with 512 references to ArtMethod
85041da59665556e8dd5601178185c68d48d645500bMathieu Chartier    env_->DeleteLocalRef(env_->ToReflectedMethod(c, mid, JNI_FALSE));
85141da59665556e8dd5601178185c68d48d645500bMathieu Chartier  }
852d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(method, nullptr);
853d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_TRUE(env_->IsInstanceOf(method, jlrConstructor));
854cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // ...and back again.
855cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  jmethodID mid2 = env_->FromReflectedMethod(method);
8562d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(mid2, nullptr);
857ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  // Make sure we can actually use it.
858d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  jstring s = reinterpret_cast<jstring>(env_->AllocObject(c));
859d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(s, nullptr);
860d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  env_->CallVoidMethod(s, mid2);
86115e9ad1d028d7f12cb598b075453173532a00d91Jeff Hao  ASSERT_EQ(JNI_FALSE, env_->ExceptionCheck());
862848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao  env_->ExceptionClear();
863d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz
864d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  mid = env_->GetMethodID(c, "length", "()I");
865d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(mid, nullptr);
866d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  // Turn the mid into a java.lang.reflect.Method...
867d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
868d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(method, nullptr);
869d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod));
870d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  // ...and back again.
871d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  mid2 = env_->FromReflectedMethod(method);
872d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(mid2, nullptr);
873d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  // Make sure we can actually use it.
874d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  s = env_->NewStringUTF("poop");
875d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz  ASSERT_NE(s, nullptr);
8765d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers  ASSERT_EQ(4, env_->CallIntMethod(s, mid2));
8772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
8782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Bad arguments.
87968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetFromReflectedMethod_ToReflectedMethodBadArgumentTest(false);
88068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetFromReflectedMethod_ToReflectedMethodBadArgumentTest(true);
881cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes}
882cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
8832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogersstatic void BogusMethod() {
8842cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  // You can't pass null function pointers to RegisterNatives.
8855174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes}
8865174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
8872d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, RegisterAndUnregisterNatives) {
8884dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlobject = env_->FindClass("java/lang/Object");
8894dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
890fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  void* native_function = reinterpret_cast<void*>(BogusMethod);
8914dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
8922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Sanity check that no exceptions are pending.
893cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  ASSERT_FALSE(env_->ExceptionCheck());
8944dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
895369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  // The following can print errors to the log we'd like to ignore.
896fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  {
897369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    ScopedLogSeverity sls(LogSeverity::FATAL);
898369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    // Check that registering method without name causes a NoSuchMethodError.
899369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    {
900369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe      JNINativeMethod methods[] = { { nullptr, "()V", native_function } };
901369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe      EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
902369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    }
903369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    ExpectException(jlnsme);
904fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz
905369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    // Check that registering method without signature causes a NoSuchMethodError.
906369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    {
907369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe      JNINativeMethod methods[] = { { "notify", nullptr, native_function } };
908369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe      EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
909369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    }
910369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    ExpectException(jlnsme);
911fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz
912369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    // Check that registering method without function causes a NoSuchMethodError.
913369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    {
914369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe      JNINativeMethod methods[] = { { "notify", "()V", nullptr } };
915369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe      EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
916369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    }
917369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    ExpectException(jlnsme);
918fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz
919369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    // Check that registering to a non-existent java.lang.Object.foo() causes a NoSuchMethodError.
920369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    {
921369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe      JNINativeMethod methods[] = { { "foo", "()V", native_function } };
922369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe      EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
923369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    }
924369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    ExpectException(jlnsme);
9254dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
926369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    // Check that registering non-native methods causes a NoSuchMethodError.
927369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    {
928369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe      JNINativeMethod methods[] = { { "equals", "(Ljava/lang/Object;)Z", native_function } };
929369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe      EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
930369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    }
931369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe    ExpectException(jlnsme);
9324dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  }
9334dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
9342d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Check that registering native methods is successful.
9354dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  {
936fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz    JNINativeMethod methods[] = { { "notify", "()V", native_function } };
9372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_OK);
9382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  }
9392d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
9402d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->UnregisterNatives(jlobject), JNI_OK);
9412d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
9422d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Check that registering no methods isn't a failure.
9432d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  {
9442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    JNINativeMethod methods[] = { };
9452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 0), JNI_OK);
9462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  }
9472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
9482d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->UnregisterNatives(jlobject), JNI_OK);
9492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
9502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Check that registering a -ve number of methods is a failure.
9512d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher check_jni_abort_catcher;
9522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  for (int i = -10; i < 0; ++i) {
9532d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    JNINativeMethod methods[] = { };
9542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->RegisterNatives(jlobject, methods, i), JNI_ERR);
9552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    check_jni_abort_catcher.Check("negative method count: ");
9564dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  }
9574dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
9585174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
9592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Unregistering a class with no natives is a warning.
9602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->UnregisterNatives(jlnsme), JNI_OK);
96168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
96268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  RegisterAndUnregisterNativesBadArguments(false, &check_jni_abort_catcher);
96368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  RegisterAndUnregisterNativesBadArguments(true, &check_jni_abort_catcher);
9644dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers}
9654dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
966ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#define EXPECT_PRIMITIVE_ARRAY(new_fn, \
967ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               get_region_fn, \
968ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               set_region_fn, \
969ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               get_elements_fn, \
970ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               release_elements_fn, \
971ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               scalar_type, \
972ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               expected_class_descriptor) \
9732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jsize size = 4; \
9742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  \
9751d99e4549309d05007d041d058b1878de88e9585Ian Rogers  { \
9761d99e4549309d05007d041d058b1878de88e9585Ian Rogers    CheckJniAbortCatcher jni_abort_catcher; \
97768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    down_cast<JNIEnvExt*>(env_)->SetCheckJniEnabled(false); \
9781d99e4549309d05007d041d058b1878de88e9585Ian Rogers    /* Allocate an negative sized array and check it has the right failure type. */ \
9792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->new_fn(-1), nullptr); \
9801d99e4549309d05007d041d058b1878de88e9585Ian Rogers    jni_abort_catcher.Check("negative array length: -1"); \
9812d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->new_fn(std::numeric_limits<jint>::min()), nullptr); \
9821d99e4549309d05007d041d058b1878de88e9585Ian Rogers    jni_abort_catcher.Check("negative array length: -2147483648"); \
9832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    /* Pass the array as null. */ \
9842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(0, env_->GetArrayLength(nullptr)); \
9852d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("java_array == null"); \
9862d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->get_region_fn(nullptr, 0, 0, nullptr); \
9872d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("java_array == null"); \
9882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->set_region_fn(nullptr, 0, 0, nullptr); \
9892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("java_array == null"); \
9902d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->get_elements_fn(nullptr, nullptr); \
9912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("java_array == null"); \
9922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->release_elements_fn(nullptr, nullptr, 0); \
9932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("java_array == null"); \
9942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    /* Pass the elements for region as null. */ \
9952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    scalar_type ## Array a = env_->new_fn(size); \
9962d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->get_region_fn(a, 0, size, nullptr); \
9972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("buf == null"); \
9982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->set_region_fn(a, 0, size, nullptr); \
9992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("buf == null"); \
100068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    down_cast<JNIEnvExt*>(env_)->SetCheckJniEnabled(true); \
10011d99e4549309d05007d041d058b1878de88e9585Ian Rogers  } \
1002814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Allocate an array and check it has the right type and length. */ \
1003814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  scalar_type ## Array a = env_->new_fn(size); \
10042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(a, nullptr); \
1005814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(a, env_->FindClass(expected_class_descriptor))); \
1006814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(size, env_->GetArrayLength(a)); \
1007d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
1008d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  /* GetPrimitiveArrayRegion/SetPrimitiveArrayRegion */ \
1009814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* AIOOBE for negative start offset. */ \
10102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->get_region_fn(a, -1, 1, nullptr); \
10112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
10122d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->set_region_fn(a, -1, 1, nullptr); \
10132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
1014d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
1015814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* AIOOBE for negative length. */ \
10162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->get_region_fn(a, 0, -1, nullptr); \
10172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
10182d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->set_region_fn(a, 0, -1, nullptr); \
10192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
1020d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
1021814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* AIOOBE for buffer overrun. */ \
10222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->get_region_fn(a, size - 1, size, nullptr); \
10232d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
10242d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->set_region_fn(a, size - 1, size, nullptr); \
10252d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
1026d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
10272cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  /* It's okay for the buffer to be null as long as the length is 0. */ \
10282d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->get_region_fn(a, 2, 0, nullptr); \
1029d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  /* Even if the offset is invalid... */ \
10302d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->get_region_fn(a, 123, 0, nullptr); \
10312d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
1032d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
10332cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  /* It's okay for the buffer to be null as long as the length is 0. */ \
10342d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->set_region_fn(a, 2, 0, nullptr); \
1035d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  /* Even if the offset is invalid... */ \
10362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->set_region_fn(a, 123, 0, nullptr); \
10372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_); \
1038d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
1039814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Prepare a couple of buffers. */ \
1040700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<scalar_type[]> src_buf(new scalar_type[size]); \
1041700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<scalar_type[]> dst_buf(new scalar_type[size]); \
1042814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  for (jsize i = 0; i < size; ++i) { src_buf[i] = scalar_type(i); } \
1043814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  for (jsize i = 0; i < size; ++i) { dst_buf[i] = scalar_type(-1); } \
1044d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  \
1045814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Copy all of src_buf onto the heap. */ \
1046ee0fa76b2e5d39ad36d1ff144b2d0270df81e606Elliott Hughes  env_->set_region_fn(a, 0, size, &src_buf[0]); \
1047814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Copy back only part. */ \
1048814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  env_->get_region_fn(a, 1, size - 2, &dst_buf[1]); \
1049ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_NE(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1050ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    << "short copy equal"; \
1051814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Copy the missing pieces. */ \
1052ee0fa76b2e5d39ad36d1ff144b2d0270df81e606Elliott Hughes  env_->get_region_fn(a, 0, 1, &dst_buf[0]); \
1053814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  env_->get_region_fn(a, size - 1, 1, &dst_buf[size - 1]); \
1054ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1055ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    << "fixed copy not equal"; \
1056814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  /* Copy back the whole array. */ \
1057ee0fa76b2e5d39ad36d1ff144b2d0270df81e606Elliott Hughes  env_->get_region_fn(a, 0, size, &dst_buf[0]); \
1058ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1059ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    << "full copy not equal"; \
10607577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  /* GetPrimitiveArrayCritical */ \
10612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  void* v = env_->GetPrimitiveArrayCritical(a, nullptr); \
1062ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_EQ(memcmp(&src_buf[0], v, size * sizeof(scalar_type)), 0) \
1063ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    << "GetPrimitiveArrayCritical not equal"; \
10647577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleasePrimitiveArrayCritical(a, v, 0); \
10657577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  /* GetXArrayElements */ \
10662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  scalar_type* xs = env_->get_elements_fn(a, nullptr); \
1067ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_EQ(memcmp(&src_buf[0], xs, size * sizeof(scalar_type)), 0) \
1068ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    << # get_elements_fn " not equal"; \
10697577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->release_elements_fn(a, xs, 0); \
1070814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
1071814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, BooleanArrays) {
1072ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion,
1073ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetBooleanArrayElements, ReleaseBooleanArrayElements, jboolean, "[Z");
1074814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1075814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, ByteArrays) {
1076ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion,
1077ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetByteArrayElements, ReleaseByteArrayElements, jbyte, "[B");
1078814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1079814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, CharArrays) {
1080ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion,
1081ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetCharArrayElements, ReleaseCharArrayElements, jchar, "[C");
1082814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1083814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, DoubleArrays) {
1084ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion,
1085ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetDoubleArrayElements, ReleaseDoubleArrayElements, jdouble, "[D");
1086814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1087814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, FloatArrays) {
1088ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion,
1089ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetFloatArrayElements, ReleaseFloatArrayElements, jfloat, "[F");
1090814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1091814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, IntArrays) {
1092ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion,
1093ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetIntArrayElements, ReleaseIntArrayElements, jint, "[I");
1094814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1095814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, LongArrays) {
1096ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion,
1097ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetLongArrayElements, ReleaseLongArrayElements, jlong, "[J");
1098814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1099814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, ShortArrays) {
1100ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion,
1101ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                         GetShortArrayElements, ReleaseShortArrayElements, jshort, "[S");
1102d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes}
1103d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes
11042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, GetPrimitiveArrayElementsOfWrongType) {
110568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetPrimitiveArrayElementsOfWrongType(false);
110668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetPrimitiveArrayElementsOfWrongType(true);
11072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers}
11082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
11092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, ReleasePrimitiveArrayElementsOfWrongType) {
111068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  ReleasePrimitiveArrayElementsOfWrongType(false);
111168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  ReleasePrimitiveArrayElementsOfWrongType(true);
11122d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers}
111368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
11142d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, GetReleasePrimitiveArrayCriticalOfWrongType) {
111568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetReleasePrimitiveArrayCriticalOfWrongType(false);
111668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetReleasePrimitiveArrayCriticalOfWrongType(true);
11172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers}
11182d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
11192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, GetPrimitiveArrayRegionElementsOfWrongType) {
112068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetPrimitiveArrayRegionElementsOfWrongType(false);
112168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  GetPrimitiveArrayRegionElementsOfWrongType(true);
11222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers}
11232d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
11242d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, SetPrimitiveArrayRegionElementsOfWrongType) {
112568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  SetPrimitiveArrayRegionElementsOfWrongType(false);
112668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  SetPrimitiveArrayRegionElementsOfWrongType(true);
11272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers}
11282d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
1129f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott HughesTEST_F(JniInternalTest, NewObjectArray) {
1130bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  jclass element_class = env_->FindClass("java/lang/String");
11312d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(element_class, nullptr);
1132bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  jclass array_class = env_->FindClass("[Ljava/lang/String;");
11332d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(array_class, nullptr);
1134f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
11351d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jobjectArray a = env_->NewObjectArray(0, element_class, nullptr);
11362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(a, nullptr);
1137bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1138bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  EXPECT_EQ(0, env_->GetArrayLength(a));
1139f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
11401d99e4549309d05007d041d058b1878de88e9585Ian Rogers  a = env_->NewObjectArray(1, element_class, nullptr);
11412d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(a, nullptr);
1142bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1143bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  EXPECT_EQ(1, env_->GetArrayLength(a));
11441d99e4549309d05007d041d058b1878de88e9585Ian Rogers  EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), nullptr));
11451d99e4549309d05007d041d058b1878de88e9585Ian Rogers
11462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Negative array length checks.
114768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  NewObjectArrayBadArguments(false);
114868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  NewObjectArrayBadArguments(true);
11491d99e4549309d05007d041d058b1878de88e9585Ian Rogers}
11501d99e4549309d05007d041d058b1878de88e9585Ian Rogers
11511d99e4549309d05007d041d058b1878de88e9585Ian RogersTEST_F(JniInternalTest, NewObjectArrayWithPrimitiveClasses) {
11521d99e4549309d05007d041d058b1878de88e9585Ian Rogers  const char* primitive_descriptors = "VZBSCIJFD";
11531d99e4549309d05007d041d058b1878de88e9585Ian Rogers  const char* primitive_names[] = {
11541d99e4549309d05007d041d058b1878de88e9585Ian Rogers      "void", "boolean", "byte", "short", "char", "int", "long", "float", "double"
11551d99e4549309d05007d041d058b1878de88e9585Ian Rogers  };
11561d99e4549309d05007d041d058b1878de88e9585Ian Rogers  ASSERT_EQ(strlen(primitive_descriptors), arraysize(primitive_names));
11571d99e4549309d05007d041d058b1878de88e9585Ian Rogers
115868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
11591d99e4549309d05007d041d058b1878de88e9585Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
11601d99e4549309d05007d041d058b1878de88e9585Ian Rogers  for (size_t i = 0; i < strlen(primitive_descriptors); ++i) {
11612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->NewObjectArray(0, nullptr, nullptr);
11622d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("element_jclass == null");
11631d99e4549309d05007d041d058b1878de88e9585Ian Rogers    jclass primitive_class = GetPrimitiveClass(primitive_descriptors[i]);
11641d99e4549309d05007d041d058b1878de88e9585Ian Rogers    env_->NewObjectArray(1, primitive_class, nullptr);
11651d99e4549309d05007d041d058b1878de88e9585Ian Rogers    std::string error_msg(StringPrintf("not an object type: %s", primitive_names[i]));
11661d99e4549309d05007d041d058b1878de88e9585Ian Rogers    jni_abort_catcher.Check(error_msg.c_str());
11671d99e4549309d05007d041d058b1878de88e9585Ian Rogers  }
116868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
116968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  for (size_t i = 0; i < strlen(primitive_descriptors); ++i) {
117068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->NewObjectArray(0, nullptr, nullptr);
117168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("NewObjectArray received NULL jclass");
117268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jclass primitive_class = GetPrimitiveClass(primitive_descriptors[i]);
117368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->NewObjectArray(1, primitive_class, nullptr);
117468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    std::string error_msg(StringPrintf("not an object type: %s", primitive_names[i]));
117568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check(error_msg.c_str());
117668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
117768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
11781d99e4549309d05007d041d058b1878de88e9585Ian Rogers}
11791d99e4549309d05007d041d058b1878de88e9585Ian Rogers
11801d99e4549309d05007d041d058b1878de88e9585Ian RogersTEST_F(JniInternalTest, NewObjectArrayWithInitialValue) {
11811d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jclass element_class = env_->FindClass("java/lang/String");
11822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(element_class, nullptr);
11831d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jclass array_class = env_->FindClass("[Ljava/lang/String;");
11842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(array_class, nullptr);
11857577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
11867577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jstring s = env_->NewStringUTF("poop");
11871d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jobjectArray a = env_->NewObjectArray(2, element_class, s);
11882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(a, nullptr);
11897577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
11907577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(2, env_->GetArrayLength(a));
11917577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), s));
11927577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 1), s));
11931d99e4549309d05007d041d058b1878de88e9585Ian Rogers
11941d99e4549309d05007d041d058b1878de88e9585Ian Rogers  // Attempt to incorrect create an array of strings with initial value of string arrays.
11951d99e4549309d05007d041d058b1878de88e9585Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
11961d99e4549309d05007d041d058b1878de88e9585Ian Rogers  env_->NewObjectArray(2, element_class, a);
11971d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jni_abort_catcher.Check("cannot assign object of type 'java.lang.String[]' to array with element "
11981d99e4549309d05007d041d058b1878de88e9585Ian Rogers                          "type of 'java.lang.String'");
1199bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes}
1200f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
1201bd9359912e5398799f60649b86ae80644ec72627Elliott HughesTEST_F(JniInternalTest, GetArrayLength) {
12022cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  // Already tested in NewObjectArray/NewPrimitiveArray except for null.
12032f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  CheckJniAbortCatcher jni_abort_catcher;
12042f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
12052f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  EXPECT_EQ(0, env_->GetArrayLength(nullptr));
12062f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  jni_abort_catcher.Check("java_array == null");
12072f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
12082f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  EXPECT_EQ(JNI_ERR, env_->GetArrayLength(nullptr));
12092f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  jni_abort_catcher.Check("jarray was NULL");
12102f022bd02badb6a3b3edd5b65416a4235c665cccIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
12118a26c5c4c74b09e2887593c733a22652a9f80d7cElliott Hughes}
12128a26c5c4c74b09e2887593c733a22652a9f80d7cElliott Hughes
121337f7a40f6789bb287f287a9af00777af9d6428eeElliott HughesTEST_F(JniInternalTest, GetObjectClass) {
121437f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass string_class = env_->FindClass("java/lang/String");
12152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(string_class, nullptr);
121637f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass class_class = env_->FindClass("java/lang/Class");
12172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(class_class, nullptr);
121837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
121937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jstring s = env_->NewStringUTF("poop");
122037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass c = env_->GetObjectClass(s);
122137f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  ASSERT_TRUE(env_->IsSameObject(string_class, c));
122237f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
122337f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass c2 = env_->GetObjectClass(c);
122437f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2)));
12252d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
12262d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Null as object should fail.
12272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
12282d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetObjectClass(nullptr), nullptr);
12292d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_object == null");
123037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes}
123137f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
1232885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott HughesTEST_F(JniInternalTest, GetSuperclass) {
1233885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jclass object_class = env_->FindClass("java/lang/Object");
12342d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(object_class, nullptr);
1235885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jclass string_class = env_->FindClass("java/lang/String");
12362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(string_class, nullptr);
1237dc18020e83aa1261d4f661f1f9330bda20dffd71Ian Rogers  jclass runnable_interface = env_->FindClass("java/lang/Runnable");
12382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(runnable_interface, nullptr);
1239885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class)));
12402d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_EQ(env_->GetSuperclass(object_class), nullptr);
1241dc18020e83aa1261d4f661f1f9330bda20dffd71Ian Rogers  ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(runnable_interface)));
12422d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
12432d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Null as class should fail.
12442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
124568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
12462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetSuperclass(nullptr), nullptr);
12472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_class == null");
124868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
124968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(env_->GetSuperclass(nullptr), nullptr);
125068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("GetSuperclass received NULL jclass");
125168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1252885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes}
1253885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
125437f7a40f6789bb287f287a9af00777af9d6428eeElliott HughesTEST_F(JniInternalTest, IsAssignableFrom) {
125537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass object_class = env_->FindClass("java/lang/Object");
12562d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(object_class, nullptr);
125737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass string_class = env_->FindClass("java/lang/String");
12582d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(string_class, nullptr);
125937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
12601268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // A superclass is assignable from an instance of its
12611268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // subclass but not vice versa.
12621268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_TRUE(env_->IsAssignableFrom(string_class, object_class));
12631268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_FALSE(env_->IsAssignableFrom(object_class, string_class));
12641268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath
12651268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  jclass charsequence_interface = env_->FindClass("java/lang/CharSequence");
12661268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_NE(charsequence_interface, nullptr);
12671268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath
12681268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // An interface is assignable from an instance of an implementing
12691268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // class but not vice versa.
12701268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_TRUE(env_->IsAssignableFrom(string_class, charsequence_interface));
12711268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_FALSE(env_->IsAssignableFrom(charsequence_interface, string_class));
12721268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath
12731268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // Check that arrays are covariant.
12741268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  jclass string_array_class = env_->FindClass("[Ljava/lang/String;");
12751268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_NE(string_array_class, nullptr);
12761268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  jclass object_array_class = env_->FindClass("[Ljava/lang/Object;");
12771268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_NE(object_array_class, nullptr);
12781268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_TRUE(env_->IsAssignableFrom(string_array_class, object_array_class));
12791268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  ASSERT_FALSE(env_->IsAssignableFrom(object_array_class, string_array_class));
12801268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath
12811268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // Primitive types are tested in 004-JniTest.
12822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
12832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Null as either class should fail.
12842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
128568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
12862d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->IsAssignableFrom(nullptr, string_class), JNI_FALSE);
12872d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_class1 == null");
12882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->IsAssignableFrom(object_class, nullptr), JNI_FALSE);
12892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_class2 == null");
129068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
129168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(env_->IsAssignableFrom(nullptr, string_class), JNI_FALSE);
129268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("IsAssignableFrom received NULL jclass");
129368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(env_->IsAssignableFrom(object_class, nullptr), JNI_FALSE);
129468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("IsAssignableFrom received NULL jclass");
129568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
129637f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes}
129737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
1298b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott HughesTEST_F(JniInternalTest, GetObjectRefType) {
1299b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jclass local = env_->FindClass("java/lang/Object");
13002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(local != nullptr);
1301b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(local));
1302b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1303b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jobject global = env_->NewGlobalRef(local);
1304b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ(JNIGlobalRefType, env_->GetObjectRefType(global));
1305b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1306b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jweak weak_global = env_->NewWeakGlobalRef(local);
1307b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ(JNIWeakGlobalRefType, env_->GetObjectRefType(weak_global));
1308b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1309a87630724ef4f8760684fa69c8ecc685735aff88Andreas Gampe  {
1310a87630724ef4f8760684fa69c8ecc685735aff88Andreas Gampe    CheckJniAbortCatcher jni_abort_catcher;
1311a87630724ef4f8760684fa69c8ecc685735aff88Andreas Gampe    jobject invalid = reinterpret_cast<jobject>(this);
1312a87630724ef4f8760684fa69c8ecc685735aff88Andreas Gampe    EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(invalid));
1313a87630724ef4f8760684fa69c8ecc685735aff88Andreas Gampe    jni_abort_catcher.Check("use of invalid jobject");
1314a87630724ef4f8760684fa69c8ecc685735aff88Andreas Gampe  }
1315b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1316b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  // TODO: invoke a native method and test that its arguments are considered local references.
13172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
1318a87630724ef4f8760684fa69c8ecc685735aff88Andreas Gampe  // Null as pointer should not fail and return invalid-ref. b/18820997
13192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(nullptr));
1320a87630724ef4f8760684fa69c8ecc685735aff88Andreas Gampe
1321a87630724ef4f8760684fa69c8ecc685735aff88Andreas Gampe  // TODO: Null as reference should return the original type.
1322a87630724ef4f8760684fa69c8ecc685735aff88Andreas Gampe  // This requires running a GC so a non-null object gets freed.
1323b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes}
1324b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
13250859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu ChartierTEST_F(JniInternalTest, StaleWeakGlobal) {
13260859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  jclass java_lang_Class = env_->FindClass("java/lang/Class");
13272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(java_lang_Class, nullptr);
13282d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jobjectArray local_ref = env_->NewObjectArray(1, java_lang_Class, nullptr);
13292d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(local_ref, nullptr);
13300859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  jweak weak_global = env_->NewWeakGlobalRef(local_ref);
13312d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(weak_global, nullptr);
13320859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  env_->DeleteLocalRef(local_ref);
13330859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  Runtime::Current()->GetHeap()->CollectGarbage(false);  // GC should clear the weak global.
13340859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  jobject new_global_ref = env_->NewGlobalRef(weak_global);
13352d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(new_global_ref, nullptr);
13360859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier  jobject new_local_ref = env_->NewLocalRef(weak_global);
13372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(new_local_ref, nullptr);
13380859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier}
13390859999b0ae32190cf8da2f2e409f7f10a0058ddMathieu Chartier
13408a26c5c4c74b09e2887593c733a22652a9f80d7cElliott HughesTEST_F(JniInternalTest, NewStringUTF) {
13412d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->NewStringUTF(nullptr), nullptr);
1342814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  jstring s;
1343814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
1344814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  s = env_->NewStringUTF("");
13452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(s, nullptr);
1346814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(0, env_->GetStringLength(s));
1347814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(0, env_->GetStringUTFLength(s));
1348814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  s = env_->NewStringUTF("hello");
13492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(s, nullptr);
1350814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(5, env_->GetStringLength(s));
1351814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(5, env_->GetStringUTFLength(s));
1352814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
1353a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  // Encoded surrogate pair.
1354a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  s = env_->NewStringUTF("\xed\xa0\x81\xed\xb0\x80");
1355a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  EXPECT_NE(s, nullptr);
1356a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  EXPECT_EQ(2, env_->GetStringLength(s));
1357e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath
1358e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  // The surrogate pair gets encoded into a 4 byte UTF sequence..
1359e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  EXPECT_EQ(4, env_->GetStringUTFLength(s));
1360a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  const char* chars = env_->GetStringUTFChars(s, nullptr);
1361e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  EXPECT_STREQ("\xf0\x90\x90\x80", chars);
1362a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  env_->ReleaseStringUTFChars(s, chars);
1363a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath
1364e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  // .. but is stored as is in the utf-16 representation.
1365e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  const jchar* jchars = env_->GetStringChars(s, nullptr);
1366e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  EXPECT_EQ(0xd801, jchars[0]);
1367e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  EXPECT_EQ(0xdc00, jchars[1]);
1368e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  env_->ReleaseStringChars(s, jchars);
1369e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath
1370a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  // 4 byte UTF sequence appended to an encoded surrogate pair.
1371a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  s = env_->NewStringUTF("\xed\xa0\x81\xed\xb0\x80 \xf0\x9f\x8f\xa0");
1372a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  EXPECT_NE(s, nullptr);
1373e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath
1374e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  // The 4 byte sequence {0xf0, 0x9f, 0x8f, 0xa0} is converted into a surrogate
1375e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  // pair {0xd83c, 0xdfe0}.
1376a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  EXPECT_EQ(5, env_->GetStringLength(s));
1377e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  jchars = env_->GetStringChars(s, nullptr);
1378e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  // The first surrogate pair, encoded as such in the input.
1379e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  EXPECT_EQ(0xd801, jchars[0]);
1380e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  EXPECT_EQ(0xdc00, jchars[1]);
1381e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  // The second surrogate pair, from the 4 byte UTF sequence in the input.
1382e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  EXPECT_EQ(0xd83c, jchars[3]);
1383e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  EXPECT_EQ(0xdfe0, jchars[4]);
1384e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  env_->ReleaseStringChars(s, jchars);
1385e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath
1386e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  EXPECT_EQ(9, env_->GetStringUTFLength(s));
1387a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  chars = env_->GetStringUTFChars(s, nullptr);
1388e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  EXPECT_STREQ("\xf0\x90\x90\x80 \xf0\x9f\x8f\xa0", chars);
1389a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  env_->ReleaseStringUTFChars(s, chars);
1390a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath
1391a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  // A string with 1, 2, 3 and 4 byte UTF sequences with spaces
1392a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  // between them
1393a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  s = env_->NewStringUTF("\x24 \xc2\xa2 \xe2\x82\xac \xf0\x9f\x8f\xa0");
1394a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  EXPECT_NE(s, nullptr);
1395a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath  EXPECT_EQ(8, env_->GetStringLength(s));
1396e16dad1d6388b0305f13e2171308a77f42e7c682Narayan Kamath  EXPECT_EQ(13, env_->GetStringUTFLength(s));
1397814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
1398814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
1399814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, NewString) {
1400814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  jchar chars[] = { 'h', 'i' };
1401814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  jstring s;
1402814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  s = env_->NewString(chars, 0);
14032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(s, nullptr);
1404814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(0, env_->GetStringLength(s));
1405814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(0, env_->GetStringUTFLength(s));
1406814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  s = env_->NewString(chars, 2);
14072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(s, nullptr);
1408814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(2, env_->GetStringLength(s));
1409814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  EXPECT_EQ(2, env_->GetStringUTFLength(s));
1410814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
14118a26c5c4c74b09e2887593c733a22652a9f80d7cElliott Hughes  // TODO: check some non-ASCII strings.
1412f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes}
1413f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
141425e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse WilsonTEST_F(JniInternalTest, NewStringNullCharsZeroLength) {
14151d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jstring s = env_->NewString(nullptr, 0);
14162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(s, nullptr);
141725e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse Wilson  EXPECT_EQ(0, env_->GetStringLength(s));
141825e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse Wilson}
141925e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse Wilson
14201d99e4549309d05007d041d058b1878de88e9585Ian RogersTEST_F(JniInternalTest, NewStringNullCharsNonzeroLength) {
14211d99e4549309d05007d041d058b1878de88e9585Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
14221d99e4549309d05007d041d058b1878de88e9585Ian Rogers  env_->NewString(nullptr, 1);
14231d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jni_abort_catcher.Check("chars == null && char_count > 0");
14241d99e4549309d05007d041d058b1878de88e9585Ian Rogers}
14251d99e4549309d05007d041d058b1878de88e9585Ian Rogers
14261d99e4549309d05007d041d058b1878de88e9585Ian RogersTEST_F(JniInternalTest, NewStringNegativeLength) {
14271d99e4549309d05007d041d058b1878de88e9585Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
142868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
14291d99e4549309d05007d041d058b1878de88e9585Ian Rogers  env_->NewString(nullptr, -1);
14301d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jni_abort_catcher.Check("char_count < 0: -1");
14311d99e4549309d05007d041d058b1878de88e9585Ian Rogers  env_->NewString(nullptr, std::numeric_limits<jint>::min());
14321d99e4549309d05007d041d058b1878de88e9585Ian Rogers  jni_abort_catcher.Check("char_count < 0: -2147483648");
143368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
143468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  env_->NewString(nullptr, -1);
143568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("negative jsize: -1");
143668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  env_->NewString(nullptr, std::numeric_limits<jint>::min());
143768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("negative jsize: -2147483648");
143868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
143925e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse Wilson}
144025e79a5e9ecd4bf30e0ea90a7dd4313f7f44bc3cJesse Wilson
1441b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott HughesTEST_F(JniInternalTest, GetStringLength_GetStringUTFLength) {
1442b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  // Already tested in the NewString/NewStringUTF tests.
1443b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes}
1444b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1445b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott HughesTEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) {
1446b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jstring s = env_->NewStringUTF("hello");
14472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(s != nullptr);
1448b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
14492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, -1, 0, nullptr);
14502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
14512d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, 0, -1, nullptr);
14522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
14532d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, 0, 10, nullptr);
14542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
14552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, 10, 1, nullptr);
14562d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
1457b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1458b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jchar chars[4] = { 'x', 'x', 'x', 'x' };
1459b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  env_->GetStringRegion(s, 1, 2, &chars[1]);
1460b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('x', chars[0]);
1461b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('e', chars[1]);
1462b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('l', chars[2]);
1463b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('x', chars[3]);
1464b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
14652cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  // It's okay for the buffer to be null as long as the length is 0.
14662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, 2, 0, nullptr);
1467d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  // Even if the offset is invalid...
14682d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringRegion(s, 123, 0, nullptr);
14692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
14702d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
14712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, -1, 0, nullptr);
14722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
14732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, 0, -1, nullptr);
14742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
14752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, 0, 10, nullptr);
14762d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
14772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, 10, 1, nullptr);
14782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
1479b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1480b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  char bytes[4] = { 'x', 'x', 'x', 'x' };
1481b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  env_->GetStringUTFRegion(s, 1, 2, &bytes[1]);
1482b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('x', bytes[0]);
1483b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('e', bytes[1]);
1484b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('l', bytes[2]);
1485b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  EXPECT_EQ('x', bytes[3]);
1486d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes
14872cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  // It's okay for the buffer to be null as long as the length is 0.
14882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, 2, 0, nullptr);
1489d7d7f6e6916d4cdba89a28670440ec3a59d1a862Elliott Hughes  // Even if the offset is invalid...
14902d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->GetStringUTFRegion(s, 123, 0, nullptr);
14912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(sioobe_);
1492b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes}
1493b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
14947577075b147fd8fa37ca41e7a32d1124676776ceElliott HughesTEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) {
14952cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  // Passing in a null jstring is ignored normally, but caught by -Xcheck:jni.
149668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
1497b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  {
1498b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    CheckJniAbortCatcher check_jni_abort_catcher;
14992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_EQ(env_->GetStringUTFChars(nullptr, nullptr), nullptr);
150068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  }
150168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  {
150268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    CheckJniAbortCatcher check_jni_abort_catcher;
150368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
150468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_EQ(env_->GetStringUTFChars(nullptr, nullptr), nullptr);
150568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    check_jni_abort_catcher.Check("GetStringUTFChars received NULL jstring");
150668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1507b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
15087577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
15097577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jstring s = env_->NewStringUTF("hello");
15102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(s != nullptr);
15117577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
15122d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  const char* utf = env_->GetStringUTFChars(s, nullptr);
15137577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_STREQ("hello", utf);
15147577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringUTFChars(s, utf);
15157577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
15167577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jboolean is_copy = JNI_FALSE;
15177577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  utf = env_->GetStringUTFChars(s, &is_copy);
15187577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(JNI_TRUE, is_copy);
15197577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_STREQ("hello", utf);
15207577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringUTFChars(s, utf);
15217577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes}
15227577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
15237577075b147fd8fa37ca41e7a32d1124676776ceElliott HughesTEST_F(JniInternalTest, GetStringChars_ReleaseStringChars) {
15247577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jstring s = env_->NewStringUTF("hello");
152556890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  ScopedObjectAccess soa(env_);
152656890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  mirror::String* s_m = soa.Decode<mirror::String*>(s);
15272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(s != nullptr);
15287577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
15297577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
15302d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  const jchar* chars = env_->GetStringChars(s, nullptr);
15317577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[0], chars[0]);
15327577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[1], chars[1]);
15337577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[2], chars[2]);
15347577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[3], chars[3]);
15357577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[4], chars[4]);
15367577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringChars(s, chars);
15377577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
15387577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jboolean is_copy = JNI_FALSE;
15397577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  chars = env_->GetStringChars(s, &is_copy);
1540848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao  if (Runtime::Current()->GetHeap()->IsMovableObject(s_m)) {
154156890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    EXPECT_EQ(JNI_TRUE, is_copy);
154256890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  } else {
154356890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    EXPECT_EQ(JNI_FALSE, is_copy);
154456890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  }
15457577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[0], chars[0]);
15467577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[1], chars[1]);
15477577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[2], chars[2]);
15487577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[3], chars[3]);
15497577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[4], chars[4]);
15507577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringChars(s, chars);
15517577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes}
15527577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
15537577075b147fd8fa37ca41e7a32d1124676776ceElliott HughesTEST_F(JniInternalTest, GetStringCritical_ReleaseStringCritical) {
15547577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jstring s = env_->NewStringUTF("hello");
15552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(s != nullptr);
15567577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
15577577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
15582d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  const jchar* chars = env_->GetStringCritical(s, nullptr);
15597577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[0], chars[0]);
15607577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[1], chars[1]);
15617577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[2], chars[2]);
15627577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[3], chars[3]);
15637577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[4], chars[4]);
15647577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringCritical(s, chars);
15657577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
156656890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  jboolean is_copy = JNI_TRUE;
15677577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  chars = env_->GetStringCritical(s, &is_copy);
156856890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih  EXPECT_EQ(JNI_FALSE, is_copy);
15697577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[0], chars[0]);
15707577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[1], chars[1]);
15717577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[2], chars[2]);
15727577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[3], chars[3]);
15737577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  EXPECT_EQ(expected[4], chars[4]);
15747577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  env_->ReleaseStringCritical(s, chars);
15757577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes}
15767577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
1577814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott HughesTEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) {
1578b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  jclass java_lang_Class = env_->FindClass("java/lang/Class");
15792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(java_lang_Class != nullptr);
1580289da82ae82438ab3aed1898c82fd87c16846e74Elliott Hughes
15812d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jobjectArray array = env_->NewObjectArray(1, java_lang_Class, nullptr);
15822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(array, nullptr);
15832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetObjectArrayElement(array, 0), nullptr);
1584b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  env_->SetObjectArrayElement(array, 0, java_lang_Class);
1585b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), java_lang_Class));
1586a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes
1587a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes  // ArrayIndexOutOfBounds for negative index.
1588b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  env_->SetObjectArrayElement(array, -1, java_lang_Class);
15892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_);
1590a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes
1591a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes  // ArrayIndexOutOfBounds for too-large index.
1592b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  env_->SetObjectArrayElement(array, 1, java_lang_Class);
15932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(aioobe_);
1594a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes
1595b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  // ArrayStoreException thrown for bad types.
1596b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  env_->SetObjectArrayElement(array, 0, env_->NewStringUTF("not a jclass!"));
15972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ExpectException(ase_);
15982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
15992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Null as array should fail.
16002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CheckJniAbortCatcher jni_abort_catcher;
160168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
16022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(nullptr, env_->GetObjectArrayElement(nullptr, 0));
16032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_array == null");
16042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->SetObjectArrayElement(nullptr, 0, nullptr);
16052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  jni_abort_catcher.Check("java_array == null");
160668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
160768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(nullptr, env_->GetObjectArrayElement(nullptr, 0));
160868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("jarray was NULL");
160968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  env_->SetObjectArrayElement(nullptr, 0, nullptr);
161068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  jni_abort_catcher.Check("jarray was NULL");
161168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1612289da82ae82438ab3aed1898c82fd87c16846e74Elliott Hughes}
1613289da82ae82438ab3aed1898c82fd87c16846e74Elliott Hughes
1614647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers#define EXPECT_STATIC_PRIMITIVE_FIELD(expect_eq, type, field_name, sig, value1, value2) \
1615885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  do { \
1616885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \
16172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_NE(fid, nullptr); \
1618885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    env_->SetStatic ## type ## Field(c, fid, value1); \
1619647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers    expect_eq(value1, env_->GetStatic ## type ## Field(c, fid)); \
1620885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    env_->SetStatic ## type ## Field(c, fid, value2); \
1621647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers    expect_eq(value2, env_->GetStatic ## type ## Field(c, fid)); \
16222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    \
162368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(false); \
162468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    { \
162568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      CheckJniAbortCatcher jni_abort_catcher; \
162668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      env_->GetStatic ## type ## Field(nullptr, fid); \
162768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      env_->SetStatic ## type ## Field(nullptr, fid, value1); \
162868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    } \
16292d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CheckJniAbortCatcher jni_abort_catcher; \
16302d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->GetStatic ## type ## Field(c, nullptr); \
16312d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("fid == null"); \
16322d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->SetStatic ## type ## Field(c, nullptr, value1); \
16332d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("fid == null"); \
163468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    \
163568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); \
163668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetStatic ## type ## Field(nullptr, fid); \
163768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("received NULL jclass"); \
163868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetStatic ## type ## Field(nullptr, fid, value1); \
163968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("received NULL jclass"); \
164068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->GetStatic ## type ## Field(c, nullptr); \
164168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("jfieldID was NULL"); \
164268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->SetStatic ## type ## Field(c, nullptr, value1); \
164368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("jfieldID was NULL"); \
164468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); \
1645885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  } while (false)
1646885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1647647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers#define EXPECT_PRIMITIVE_FIELD(expect_eq, instance, type, field_name, sig, value1, value2) \
1648885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  do { \
1649885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    jfieldID fid = env_->GetFieldID(c, field_name, sig); \
16502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    EXPECT_NE(fid, nullptr); \
1651885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    env_->Set ## type ## Field(instance, fid, value1); \
1652647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers    expect_eq(value1, env_->Get ## type ## Field(instance, fid)); \
1653885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    env_->Set ## type ## Field(instance, fid, value2); \
1654647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers    expect_eq(value2, env_->Get ## type ## Field(instance, fid)); \
16552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    \
165668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(false); \
16572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CheckJniAbortCatcher jni_abort_catcher; \
16582d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->Get ## type ## Field(nullptr, fid); \
16592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("obj == null"); \
16602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->Set ## type ## Field(nullptr, fid, value1); \
16612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("obj == null"); \
16622d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->Get ## type ## Field(instance, nullptr); \
16632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("fid == null"); \
16642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->Set ## type ## Field(instance, nullptr, value1); \
16652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    jni_abort_catcher.Check("fid == null"); \
166668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); \
166768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->Get ## type ## Field(nullptr, fid); \
166868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("field operation on NULL object:"); \
166968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->Set ## type ## Field(nullptr, fid, value1); \
167068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("field operation on NULL object:"); \
167168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->Get ## type ## Field(instance, nullptr); \
167268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("jfieldID was NULL"); \
167368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    env_->Set ## type ## Field(instance, nullptr, value1); \
167468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    jni_abort_catcher.Check("jfieldID was NULL"); \
167568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); \
1676885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  } while (false)
1677885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1678885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1679885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott HughesTEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) {
168000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Thread::Current()->TransitionFromSuspendedToRunnable();
168100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  LoadDex("AllFields");
1682bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom  bool started = runtime_->Start();
16832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(started);
1684885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1685885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jclass c = env_->FindClass("AllFields");
16862d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
1687885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jobject o = env_->AllocObject(c);
16882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
1689885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1690647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Boolean, "sZ", "Z", JNI_TRUE, JNI_FALSE);
1691647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Byte, "sB", "B", 1, 2);
1692647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Char, "sC", "C", 'a', 'b');
1693647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_DOUBLE_EQ, Double, "sD", "D", 1.0, 2.0);
1694647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_FLOAT_EQ, Float, "sF", "F", 1.0, 2.0);
1695647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Int, "sI", "I", 1, 2);
1696647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Long, "sJ", "J", 1, 2);
1697647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Short, "sS", "S", 1, 2);
1698647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers
1699647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Boolean, "iZ", "Z", JNI_TRUE, JNI_FALSE);
1700647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Byte, "iB", "B", 1, 2);
1701647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Char, "iC", "C", 'a', 'b');
1702647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_DOUBLE_EQ, o, Double, "iD", "D", 1.0, 2.0);
1703647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_FLOAT_EQ, o, Float, "iF", "F", 1.0, 2.0);
1704647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Int, "iI", "I", 1, 2);
1705647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Long, "iJ", "J", 1, 2);
1706647b1a86f518d8db0331b3d52a96392b7a62504bIan Rogers  EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Short, "iS", "S", 1, 2);
1707885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes}
1708885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1709885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott HughesTEST_F(JniInternalTest, GetObjectField_SetObjectField) {
171000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Thread::Current()->TransitionFromSuspendedToRunnable();
171100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  LoadDex("AllFields");
171225c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom  runtime_->Start();
1713885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1714885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jclass c = env_->FindClass("AllFields");
17152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(c, nullptr);
1716885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jobject o = env_->AllocObject(c);
17172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
1718885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1719885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jstring s1 = env_->NewStringUTF("hello");
17202d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s1, nullptr);
1721885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jstring s2 = env_->NewStringUTF("world");
17222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s2, nullptr);
1723885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1724885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;");
17252d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s_fid, nullptr);
1726885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;");
17272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(i_fid, nullptr);
1728885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1729885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  env_->SetStaticObjectField(c, s_fid, s1);
1730885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid)));
1731885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  env_->SetStaticObjectField(c, s_fid, s2);
1732885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid)));
1733885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1734885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  env_->SetObjectField(o, i_fid, s1);
1735885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid)));
1736885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  env_->SetObjectField(o, i_fid, s2);
1737885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid)));
1738885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes}
1739885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
17402d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, NewLocalRef_nullptr) {
17412d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->NewLocalRef(nullptr), nullptr);
174218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
174318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
174418c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, NewLocalRef) {
174518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
17462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
174718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewLocalRef(s);
17482d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, nullptr);
17492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, s);
175018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
17512ced6a534157d5d963693346904389c19775d2daElliott Hughes  EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(o));
175218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
175318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
17542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, DeleteLocalRef_nullptr) {
17552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->DeleteLocalRef(nullptr);
175618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
175718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
175818c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, DeleteLocalRef) {
1759369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  // This tests leads to warnings and errors in the log.
1760369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  ScopedLogSeverity sls(LogSeverity::FATAL);
1761369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe
176218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
17632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
176418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteLocalRef(s);
176518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
17663f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes  // Currently, deleting an already-deleted reference is just a CheckJNI warning.
1767b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  {
176868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(false);
176968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    {
177068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      CheckJniAbortCatcher check_jni_abort_catcher;
177168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      env_->DeleteLocalRef(s);
177268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    }
1773b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    CheckJniAbortCatcher check_jni_abort_catcher;
177468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
1775b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    env_->DeleteLocalRef(s);
1776c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    std::string expected(StringPrintf("use of deleted local reference %p", s));
1777a9137c6bbdf4a1883f7b3f836c269eeb2ff619b2Elliott Hughes    check_jni_abort_catcher.Check(expected.c_str());
177868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1779b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
178018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
178118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  s = env_->NewStringUTF("");
17822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
178318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewLocalRef(s);
17842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
178518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
178618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteLocalRef(s);
178718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteLocalRef(o);
178818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
178918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
1790aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott HughesTEST_F(JniInternalTest, PushLocalFrame_10395422) {
1791aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // The JNI specification is ambiguous about whether the given capacity is to be interpreted as a
1792aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // maximum or as a minimum, but it seems like it's supposed to be a minimum, and that's how
1793aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // Android historically treated it, and it's how the RI treats it. It's also the more useful
1794aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // interpretation!
1795aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  ASSERT_EQ(JNI_OK, env_->PushLocalFrame(0));
17962d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->PopLocalFrame(nullptr);
1797aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes
1798369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  // The following two tests will print errors to the log.
1799369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  ScopedLogSeverity sls(LogSeverity::FATAL);
1800369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe
1801aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // Negative capacities are not allowed.
1802aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(-1));
1803aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes
1804aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  // And it's okay to have an upper limit. Ours is currently 512.
1805aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes  ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(8192));
1806aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes}
1807aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes
18082ced6a534157d5d963693346904389c19775d2daElliott HughesTEST_F(JniInternalTest, PushLocalFrame_PopLocalFrame) {
1809369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  // This tests leads to errors in the log.
1810369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  ScopedLogSeverity sls(LogSeverity::FATAL);
1811369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe
18122ced6a534157d5d963693346904389c19775d2daElliott Hughes  jobject original = env_->NewStringUTF("");
18132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(original, nullptr);
18142ced6a534157d5d963693346904389c19775d2daElliott Hughes
18152ced6a534157d5d963693346904389c19775d2daElliott Hughes  jobject outer;
18162ced6a534157d5d963693346904389c19775d2daElliott Hughes  jobject inner1, inner2;
181700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(env_);
18182ced6a534157d5d963693346904389c19775d2daElliott Hughes  {
1819aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes    ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
18202ced6a534157d5d963693346904389c19775d2daElliott Hughes    outer = env_->NewLocalRef(original);
18212ced6a534157d5d963693346904389c19775d2daElliott Hughes
18222ced6a534157d5d963693346904389c19775d2daElliott Hughes    {
1823aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes      ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
18242ced6a534157d5d963693346904389c19775d2daElliott Hughes      inner1 = env_->NewLocalRef(outer);
18252ced6a534157d5d963693346904389c19775d2daElliott Hughes      inner2 = env_->NewStringUTF("survivor");
1826c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      EXPECT_NE(env_->PopLocalFrame(inner2), nullptr);
18272ced6a534157d5d963693346904389c19775d2daElliott Hughes    }
18282ced6a534157d5d963693346904389c19775d2daElliott Hughes
18292ced6a534157d5d963693346904389c19775d2daElliott Hughes    EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
18302ced6a534157d5d963693346904389c19775d2daElliott Hughes    EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(outer));
1831c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    {
1832c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      CheckJniAbortCatcher check_jni_abort_catcher;
1833c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
1834c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      check_jni_abort_catcher.Check("use of deleted local reference");
1835c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    }
18362ced6a534157d5d963693346904389c19775d2daElliott Hughes
18372ced6a534157d5d963693346904389c19775d2daElliott Hughes    // Our local reference for the survivor is invalid because the survivor
18382ced6a534157d5d963693346904389c19775d2daElliott Hughes    // gets a new local reference...
1839c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    {
1840c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      CheckJniAbortCatcher check_jni_abort_catcher;
1841c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
1842c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      check_jni_abort_catcher.Check("use of deleted local reference");
1843c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    }
18442ced6a534157d5d963693346904389c19775d2daElliott Hughes
1845c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    EXPECT_EQ(env_->PopLocalFrame(nullptr), nullptr);
18462ced6a534157d5d963693346904389c19775d2daElliott Hughes  }
18472ced6a534157d5d963693346904389c19775d2daElliott Hughes  EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
1848c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  CheckJniAbortCatcher check_jni_abort_catcher;
18492ced6a534157d5d963693346904389c19775d2daElliott Hughes  EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(outer));
1850c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  check_jni_abort_catcher.Check("use of deleted local reference");
18512ced6a534157d5d963693346904389c19775d2daElliott Hughes  EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
1852c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  check_jni_abort_catcher.Check("use of deleted local reference");
18532ced6a534157d5d963693346904389c19775d2daElliott Hughes  EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
1854c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  check_jni_abort_catcher.Check("use of deleted local reference");
18552ced6a534157d5d963693346904389c19775d2daElliott Hughes}
18562ced6a534157d5d963693346904389c19775d2daElliott Hughes
18572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, NewGlobalRef_nullptr) {
18582d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->NewGlobalRef(nullptr), nullptr);
185918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
186018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
186118c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, NewGlobalRef) {
186218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
18632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
186418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewGlobalRef(s);
18652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, nullptr);
18662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, s);
186718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
18682d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetObjectRefType(o), JNIGlobalRefType);
186918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
187018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
18712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, DeleteGlobalRef_nullptr) {
18722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->DeleteGlobalRef(nullptr);
187318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
187418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
187518c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, DeleteGlobalRef) {
1876369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  // This tests leads to warnings and errors in the log.
1877369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  ScopedLogSeverity sls(LogSeverity::FATAL);
1878369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe
187918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
18802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
188118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
188218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewGlobalRef(s);
18832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
188418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteGlobalRef(o);
188518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
18863f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes  // Currently, deleting an already-deleted reference is just a CheckJNI warning.
1887b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  {
188868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(false);
188968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    {
189068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      CheckJniAbortCatcher check_jni_abort_catcher;
189168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      env_->DeleteGlobalRef(o);
189268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    }
1893b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    CheckJniAbortCatcher check_jni_abort_catcher;
189468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
1895b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    env_->DeleteGlobalRef(o);
1896c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    std::string expected(StringPrintf("use of deleted global reference %p", o));
1897a9137c6bbdf4a1883f7b3f836c269eeb2ff619b2Elliott Hughes    check_jni_abort_catcher.Check(expected.c_str());
189868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1899b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
190018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
190118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o1 = env_->NewGlobalRef(s);
19022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o1, nullptr);
190318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o2 = env_->NewGlobalRef(s);
19042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o2, nullptr);
190518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
190618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteGlobalRef(o1);
190718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteGlobalRef(o2);
190818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
190918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
19102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, NewWeakGlobalRef_nullptr) {
19112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->NewWeakGlobalRef(nullptr),   nullptr);
191218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
191318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
191418c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, NewWeakGlobalRef) {
191518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
19162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
191718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewWeakGlobalRef(s);
19182d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, nullptr);
19192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_NE(o, s);
192018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
19212d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(env_->GetObjectRefType(o), JNIWeakGlobalRefType);
192218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
192318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
19242d10b206f9d0b97396b7dadb9a6415cd39efd341Ian RogersTEST_F(JniInternalTest, DeleteWeakGlobalRef_nullptr) {
19252d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  env_->DeleteWeakGlobalRef(nullptr);
192618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
192718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
192818c0753c1659629021b4becdaa3f6ea81aecce35Elliott HughesTEST_F(JniInternalTest, DeleteWeakGlobalRef) {
1929369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  // This tests leads to warnings and errors in the log.
1930369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  ScopedLogSeverity sls(LogSeverity::FATAL);
1931369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe
193218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jstring s = env_->NewStringUTF("");
19332d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(s, nullptr);
193418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
193518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o = env_->NewWeakGlobalRef(s);
19362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o, nullptr);
193718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteWeakGlobalRef(o);
193818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
19393f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes  // Currently, deleting an already-deleted reference is just a CheckJNI warning.
1940b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  {
194168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    bool old_check_jni = vm_->SetCheckJniEnabled(false);
194268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    {
194368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      CheckJniAbortCatcher check_jni_abort_catcher;
194468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      env_->DeleteWeakGlobalRef(o);
194568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    }
1946b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    CheckJniAbortCatcher check_jni_abort_catcher;
194768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
1948b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    env_->DeleteWeakGlobalRef(o);
1949c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    std::string expected(StringPrintf("use of deleted weak global reference %p", o));
1950a9137c6bbdf4a1883f7b3f836c269eeb2ff619b2Elliott Hughes    check_jni_abort_catcher.Check(expected.c_str());
195168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1952b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
195318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
195418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o1 = env_->NewWeakGlobalRef(s);
19552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o1, nullptr);
195618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  jobject o2 = env_->NewWeakGlobalRef(s);
19572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(o2, nullptr);
195818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
195918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteWeakGlobalRef(o1);
196018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  env_->DeleteWeakGlobalRef(o2);
196118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes}
196218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
19633a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei ZavjalovTEST_F(JniInternalTest, ExceptionDescribe) {
19643a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov  // This checks how ExceptionDescribe handles call without exception.
19653a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov  env_->ExceptionClear();
19663a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov  env_->ExceptionDescribe();
19673a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov}
19683a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov
196937f7a40f6789bb287f287a9af00777af9d6428eeElliott HughesTEST_F(JniInternalTest, Throw) {
197037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass exception_class = env_->FindClass("java/lang/RuntimeException");
19712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(exception_class != nullptr);
197237f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class));
19732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(exception != nullptr);
197437f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
197537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  EXPECT_EQ(JNI_OK, env_->Throw(exception));
197637f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  EXPECT_TRUE(env_->ExceptionCheck());
1977a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes  jthrowable thrown_exception = env_->ExceptionOccurred();
197837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  env_->ExceptionClear();
1979a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes  EXPECT_TRUE(env_->IsSameObject(exception, thrown_exception));
198037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
198168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  // Bad argument.
198268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
19832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(JNI_ERR, env_->Throw(nullptr));
198468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
198568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  CheckJniAbortCatcher check_jni_abort_catcher;
198668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(JNI_ERR, env_->Throw(nullptr));
198768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  check_jni_abort_catcher.Check("Throw received NULL jthrowable");
198868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
198968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers}
199037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
199168d8b42ddec39ec0174162d90d4abaa004d1983eIan RogersTEST_F(JniInternalTest, ThrowNew) {
199237f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  jclass exception_class = env_->FindClass("java/lang/RuntimeException");
19932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_TRUE(exception_class != nullptr);
199437f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
19955cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  jthrowable thrown_exception;
19965cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes
199737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
199837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  EXPECT_TRUE(env_->ExceptionCheck());
19995cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  thrown_exception = env_->ExceptionOccurred();
20005cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  env_->ExceptionClear();
20015cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
20025cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes
20032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, nullptr));
20045cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  EXPECT_TRUE(env_->ExceptionCheck());
20055cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  thrown_exception = env_->ExceptionOccurred();
200637f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  env_->ExceptionClear();
2007a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes  EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
200868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
200968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  // Bad argument.
201068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  bool old_check_jni = vm_->SetCheckJniEnabled(false);
201168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  CheckJniAbortCatcher check_jni_abort_catcher;
201268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(JNI_ERR, env_->ThrowNew(nullptr, nullptr));
201368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  check_jni_abort_catcher.Check("c == null");
201468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
201568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_EQ(JNI_ERR, env_->ThrowNew(nullptr, nullptr));
201668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  check_jni_abort_catcher.Check("ThrowNew received NULL jclass");
201768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
201837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes}
201937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
20201d99e4549309d05007d041d058b1878de88e9585Ian RogersTEST_F(JniInternalTest, NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) {
20211d99e4549309d05007d041d058b1878de88e9585Ian Rogers  // Start runtime.
20221d99e4549309d05007d041d058b1878de88e9585Ian Rogers  Thread* self = Thread::Current();
20231d99e4549309d05007d041d058b1878de88e9585Ian Rogers  self->TransitionFromSuspendedToRunnable();
20241d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.lang.Class");
20251d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.lang.Object");
20261d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.DirectByteBuffer");
20271d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.MemoryBlock");
20281d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.MemoryBlock$UnmanagedBlock");
20291d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.MappedByteBuffer");
20301d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.ByteBuffer");
20311d99e4549309d05007d041d058b1878de88e9585Ian Rogers  MakeExecutable(nullptr, "java.nio.Buffer");
20321d99e4549309d05007d041d058b1878de88e9585Ian Rogers  // TODO: we only load a dex file here as starting the runtime relies upon it.
20331d99e4549309d05007d041d058b1878de88e9585Ian Rogers  const char* class_name = "StaticLeafMethods";
20341d99e4549309d05007d041d058b1878de88e9585Ian Rogers  LoadDex(class_name);
20351d99e4549309d05007d041d058b1878de88e9585Ian Rogers  bool started = runtime_->Start();
20361d99e4549309d05007d041d058b1878de88e9585Ian Rogers  ASSERT_TRUE(started);
20371d99e4549309d05007d041d058b1878de88e9585Ian Rogers
2038b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jclass buffer_class = env_->FindClass("java/nio/Buffer");
20392d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(buffer_class, nullptr);
2040b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
2041b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  char bytes[1024];
2042b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes));
20432d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(buffer, nullptr);
2044b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class));
20452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_EQ(env_->GetDirectBufferAddress(buffer), bytes);
20461ee99352d85a07558688365dba70e9aa8f476c03Ian Rogers  ASSERT_EQ(env_->GetDirectBufferCapacity(buffer), static_cast<jlong>(sizeof(bytes)));
204745d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom
204845d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom  {
204945d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom    CheckJniAbortCatcher check_jni_abort_catcher;
205085a93364e5111dc56a73eed0130856e66cab0802Brian Carlstrom    env_->NewDirectByteBuffer(bytes, static_cast<jlong>(INT_MAX) + 1);
205145d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom    check_jni_abort_catcher.Check("in call to NewDirectByteBuffer");
205245d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom  }
2053b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes}
2054b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
20556d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian RogersTEST_F(JniInternalTest, MonitorEnterExit) {
2056369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  // This will print some error messages. Suppress.
2057369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  ScopedLogSeverity sls(LogSeverity::FATAL);
2058369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe
20592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  // Create an object to torture.
20606d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  jclass object_class = env_->FindClass("java/lang/Object");
20612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(object_class, nullptr);
20626d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  jobject object = env_->AllocObject(object_class);
20632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(object, nullptr);
20646d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
20656d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Expected class of exceptions
20666d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  jclass imse_class = env_->FindClass("java/lang/IllegalMonitorStateException");
20672d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  ASSERT_NE(imse_class, nullptr);
20686d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
20696d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  jthrowable thrown_exception;
20706d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
20716d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Unlock of unowned monitor
20726d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->MonitorExit(object);
20736d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_TRUE(env_->ExceptionCheck());
20746d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  thrown_exception = env_->ExceptionOccurred();
20756d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->ExceptionClear();
20766d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
20776d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
20786d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Lock of unowned monitor
20796d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->MonitorEnter(object);
20806d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
20816d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Regular unlock
20826d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->MonitorExit(object);
20836d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_FALSE(env_->ExceptionCheck());
20846d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
20856d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Recursively lock a lot
20866d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  size_t max_recursive_lock = 1024;
20876d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  for (size_t i = 0; i < max_recursive_lock; i++) {
20886d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    env_->MonitorEnter(object);
20896d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    EXPECT_FALSE(env_->ExceptionCheck());
20906d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  }
20916d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Recursively unlock a lot
20926d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  for (size_t i = 0; i < max_recursive_lock; i++) {
20936d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    env_->MonitorExit(object);
20946d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    EXPECT_FALSE(env_->ExceptionCheck());
20956d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  }
20966d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
20976d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Unlock of unowned monitor
20986d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->MonitorExit(object);
20996d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_TRUE(env_->ExceptionCheck());
21006d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  thrown_exception = env_->ExceptionOccurred();
21016d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  env_->ExceptionClear();
21026d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
2103a92853eb60fbce1fa6d3bbd6a6013fb514fdf5cbElliott Hughes
21042cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  // It's an error to call MonitorEnter or MonitorExit on null.
2105b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  {
2106b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    CheckJniAbortCatcher check_jni_abort_catcher;
21072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->MonitorEnter(nullptr);
2108b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    check_jni_abort_catcher.Check("in call to MonitorEnter");
21092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    env_->MonitorExit(nullptr);
2110b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes    check_jni_abort_catcher.Check("in call to MonitorExit");
2111b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes  }
21126d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers}
21136d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
21140cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers}  // namespace art
2115