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