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